diff --git a/public/.nojekyll b/public/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/public/404.html b/public/404.html new file mode 100644 index 00000000..5e71c9e4 --- /dev/null +++ b/public/404.html @@ -0,0 +1,167 @@ + + + + + + + NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+

+ This is not the page you were looking for +

+
+ +
+ + + + + + + + + diff --git a/public/CNAME b/public/CNAME new file mode 100644 index 00000000..2a9f7b68 --- /dev/null +++ b/public/CNAME @@ -0,0 +1 @@ +learning.nceas.ucsb.edu diff --git a/public/categories/index.html b/public/categories/index.html new file mode 100644 index 00000000..67a719bb --- /dev/null +++ b/public/categories/index.html @@ -0,0 +1,186 @@ + + + + + + + NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+

+ Categories +

+ +
+
+
+ + +
+ + +
+ +
+
+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/categories/index.xml b/public/categories/index.xml new file mode 100644 index 00000000..5009cc7e --- /dev/null +++ b/public/categories/index.xml @@ -0,0 +1,14 @@ + + + + Categories on NCEAS Training Materials Catalog + /categories/ + Recent content in Categories on NCEAS Training Materials Catalog + Hugo -- gohugo.io + en-us + + + + + + \ No newline at end of file diff --git a/public/cover.png b/public/cover.png new file mode 100644 index 00000000..7d7da0cb Binary files /dev/null and b/public/cover.png differ diff --git a/public/css/ADC.css b/public/css/ADC.css new file mode 100644 index 00000000..09707026 --- /dev/null +++ b/public/css/ADC.css @@ -0,0 +1,46 @@ +#NSFlogo { + width: 40%; + margin: 1em; +} + +#nceaslogo { + width: 80%; + margin-left: -1em; +} + +.bg-dark-green { + background-image: linear-gradient(to right, #5d9140, #137752); +} + +.bg-light-gray { + background-color: #bdbcbb; + padding: 5px; +} + +.ul-custom { + list-style: none; /* Remove default bullets */ +} + +.ul-custom li::before { + content: "\2022"; /* Add content: \2022 is the CSS Code/unicode for a bullet */ + color: #F4F4F4; /* Change the color */ + display: inline-block; /* Needed to add space between the bullet and the text */ + width: 0; /* Also needed for space (tweak if needed) */ + margin-left: -2em; /* Also needed for space (tweak if needed) */ + padding: 10px; +} + + +@media only screen and (max-width: 600px) { + .sidebar { + background-color: near-white; + } +} + +@media only screen and (min-width: 601px) { + .sidebar { + position: -webkit-sticky; + position: sticky; + top: 0; + } +} \ No newline at end of file diff --git a/public/dist/css/app.1cb140d8ba31d5b2f1114537dd04802a.css b/public/dist/css/app.1cb140d8ba31d5b2f1114537dd04802a.css new file mode 100644 index 00000000..ba1b08fd --- /dev/null +++ b/public/dist/css/app.1cb140d8ba31d5b2f1114537dd04802a.css @@ -0,0 +1,3 @@ +/*! TACHYONS v4.9.1 | http://tachyons.io */ + +/*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}.border-box,a,article,aside,blockquote,body,code,dd,div,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,html,input[type=email],input[type=number],input[type=password],input[type=tel],input[type=text],input[type=url],legend,li,main,nav,ol,p,pre,section,table,td,textarea,th,tr,ul{box-sizing:border-box}.aspect-ratio{height:0;position:relative}.aspect-ratio--16x9{padding-bottom:56.25%}.aspect-ratio--9x16{padding-bottom:177.77%}.aspect-ratio--4x3{padding-bottom:75%}.aspect-ratio--3x4{padding-bottom:133.33%}.aspect-ratio--6x4{padding-bottom:66.6%}.aspect-ratio--4x6{padding-bottom:150%}.aspect-ratio--8x5{padding-bottom:62.5%}.aspect-ratio--5x8{padding-bottom:160%}.aspect-ratio--7x5{padding-bottom:71.42%}.aspect-ratio--5x7{padding-bottom:140%}.aspect-ratio--1x1{padding-bottom:100%}.aspect-ratio--object{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;z-index:100}@media screen and (min-width:30em){.aspect-ratio-ns{height:0;position:relative}.aspect-ratio--16x9-ns{padding-bottom:56.25%}.aspect-ratio--9x16-ns{padding-bottom:177.77%}.aspect-ratio--4x3-ns{padding-bottom:75%}.aspect-ratio--3x4-ns{padding-bottom:133.33%}.aspect-ratio--6x4-ns{padding-bottom:66.6%}.aspect-ratio--4x6-ns{padding-bottom:150%}.aspect-ratio--8x5-ns{padding-bottom:62.5%}.aspect-ratio--5x8-ns{padding-bottom:160%}.aspect-ratio--7x5-ns{padding-bottom:71.42%}.aspect-ratio--5x7-ns{padding-bottom:140%}.aspect-ratio--1x1-ns{padding-bottom:100%}.aspect-ratio--object-ns{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;z-index:100}}@media screen and (min-width:30em) and (max-width:60em){.aspect-ratio-m{height:0;position:relative}.aspect-ratio--16x9-m{padding-bottom:56.25%}.aspect-ratio--9x16-m{padding-bottom:177.77%}.aspect-ratio--4x3-m{padding-bottom:75%}.aspect-ratio--3x4-m{padding-bottom:133.33%}.aspect-ratio--6x4-m{padding-bottom:66.6%}.aspect-ratio--4x6-m{padding-bottom:150%}.aspect-ratio--8x5-m{padding-bottom:62.5%}.aspect-ratio--5x8-m{padding-bottom:160%}.aspect-ratio--7x5-m{padding-bottom:71.42%}.aspect-ratio--5x7-m{padding-bottom:140%}.aspect-ratio--1x1-m{padding-bottom:100%}.aspect-ratio--object-m{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;z-index:100}}@media screen and (min-width:60em){.aspect-ratio-l{height:0;position:relative}.aspect-ratio--16x9-l{padding-bottom:56.25%}.aspect-ratio--9x16-l{padding-bottom:177.77%}.aspect-ratio--4x3-l{padding-bottom:75%}.aspect-ratio--3x4-l{padding-bottom:133.33%}.aspect-ratio--6x4-l{padding-bottom:66.6%}.aspect-ratio--4x6-l{padding-bottom:150%}.aspect-ratio--8x5-l{padding-bottom:62.5%}.aspect-ratio--5x8-l{padding-bottom:160%}.aspect-ratio--7x5-l{padding-bottom:71.42%}.aspect-ratio--5x7-l{padding-bottom:140%}.aspect-ratio--1x1-l{padding-bottom:100%}.aspect-ratio--object-l{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;z-index:100}}img{max-width:100%}.cover{background-size:cover!important}.contain{background-size:contain!important}@media screen and (min-width:30em){.cover-ns{background-size:cover!important}.contain-ns{background-size:contain!important}}@media screen and (min-width:30em) and (max-width:60em){.cover-m{background-size:cover!important}.contain-m{background-size:contain!important}}@media screen and (min-width:60em){.cover-l{background-size:cover!important}.contain-l{background-size:contain!important}}.bg-center{background-position:50%}.bg-center,.bg-top{background-repeat:no-repeat}.bg-top{background-position:top}.bg-right{background-position:100%}.bg-bottom,.bg-right{background-repeat:no-repeat}.bg-bottom{background-position:bottom}.bg-left{background-repeat:no-repeat;background-position:0}@media screen and (min-width:30em){.bg-center-ns{background-position:50%}.bg-center-ns,.bg-top-ns{background-repeat:no-repeat}.bg-top-ns{background-position:top}.bg-right-ns{background-position:100%}.bg-bottom-ns,.bg-right-ns{background-repeat:no-repeat}.bg-bottom-ns{background-position:bottom}.bg-left-ns{background-repeat:no-repeat;background-position:0}}@media screen and (min-width:30em) and (max-width:60em){.bg-center-m{background-position:50%}.bg-center-m,.bg-top-m{background-repeat:no-repeat}.bg-top-m{background-position:top}.bg-right-m{background-position:100%}.bg-bottom-m,.bg-right-m{background-repeat:no-repeat}.bg-bottom-m{background-position:bottom}.bg-left-m{background-repeat:no-repeat;background-position:0}}@media screen and (min-width:60em){.bg-center-l{background-position:50%}.bg-center-l,.bg-top-l{background-repeat:no-repeat}.bg-top-l{background-position:top}.bg-right-l{background-position:100%}.bg-bottom-l,.bg-right-l{background-repeat:no-repeat}.bg-bottom-l{background-position:bottom}.bg-left-l{background-repeat:no-repeat;background-position:0}}.outline{outline:1px solid}.outline-transparent{outline:1px solid transparent}.outline-0{outline:0}@media screen and (min-width:30em){.outline-ns{outline:1px solid}.outline-transparent-ns{outline:1px solid transparent}.outline-0-ns{outline:0}}@media screen and (min-width:30em) and (max-width:60em){.outline-m{outline:1px solid}.outline-transparent-m{outline:1px solid transparent}.outline-0-m{outline:0}}@media screen and (min-width:60em){.outline-l{outline:1px solid}.outline-transparent-l{outline:1px solid transparent}.outline-0-l{outline:0}}.ba{border-style:solid;border-width:1px}.bt{border-top-style:solid;border-top-width:1px}.br{border-right-style:solid;border-right-width:1px}.bb{border-bottom-style:solid;border-bottom-width:1px}.bl{border-left-style:solid;border-left-width:1px}.bn{border-style:none;border-width:0}@media screen and (min-width:30em){.ba-ns{border-style:solid;border-width:1px}.bt-ns{border-top-style:solid;border-top-width:1px}.br-ns{border-right-style:solid;border-right-width:1px}.bb-ns{border-bottom-style:solid;border-bottom-width:1px}.bl-ns{border-left-style:solid;border-left-width:1px}.bn-ns{border-style:none;border-width:0}}@media screen and (min-width:30em) and (max-width:60em){.ba-m{border-style:solid;border-width:1px}.bt-m{border-top-style:solid;border-top-width:1px}.br-m{border-right-style:solid;border-right-width:1px}.bb-m{border-bottom-style:solid;border-bottom-width:1px}.bl-m{border-left-style:solid;border-left-width:1px}.bn-m{border-style:none;border-width:0}}@media screen and (min-width:60em){.ba-l{border-style:solid;border-width:1px}.bt-l{border-top-style:solid;border-top-width:1px}.br-l{border-right-style:solid;border-right-width:1px}.bb-l{border-bottom-style:solid;border-bottom-width:1px}.bl-l{border-left-style:solid;border-left-width:1px}.bn-l{border-style:none;border-width:0}}.b--black{border-color:#000}.b--near-black{border-color:#111}.b--dark-gray{border-color:#333}.b--mid-gray{border-color:#555}.b--gray{border-color:#777}.b--silver{border-color:#999}.b--light-silver{border-color:#aaa}.b--moon-gray{border-color:#ccc}.b--light-gray{border-color:#eee}.b--near-white{border-color:#f4f4f4}.b--white{border-color:#fff}.b--white-90{border-color:hsla(0,0%,100%,.9)}.b--white-80{border-color:hsla(0,0%,100%,.8)}.b--white-70{border-color:hsla(0,0%,100%,.7)}.b--white-60{border-color:hsla(0,0%,100%,.6)}.b--white-50{border-color:hsla(0,0%,100%,.5)}.b--white-40{border-color:hsla(0,0%,100%,.4)}.b--white-30{border-color:hsla(0,0%,100%,.3)}.b--white-20{border-color:hsla(0,0%,100%,.2)}.b--white-10{border-color:hsla(0,0%,100%,.1)}.b--white-05{border-color:hsla(0,0%,100%,.05)}.b--white-025{border-color:hsla(0,0%,100%,.025)}.b--white-0125{border-color:hsla(0,0%,100%,.0125)}.b--black-90{border-color:rgba(0,0,0,.9)}.b--black-80{border-color:rgba(0,0,0,.8)}.b--black-70{border-color:rgba(0,0,0,.7)}.b--black-60{border-color:rgba(0,0,0,.6)}.b--black-50{border-color:rgba(0,0,0,.5)}.b--black-40{border-color:rgba(0,0,0,.4)}.b--black-30{border-color:rgba(0,0,0,.3)}.b--black-20{border-color:rgba(0,0,0,.2)}.b--black-10{border-color:rgba(0,0,0,.1)}.b--black-05{border-color:rgba(0,0,0,.05)}.b--black-025{border-color:rgba(0,0,0,.025)}.b--black-0125{border-color:rgba(0,0,0,.0125)}.b--dark-red{border-color:#e7040f}.b--red{border-color:#ff4136}.b--light-red{border-color:#ff725c}.b--orange{border-color:#ff6300}.b--gold{border-color:#ffb700}.b--yellow{border-color:gold}.b--light-yellow{border-color:#fbf1a9}.b--purple{border-color:#5e2ca5}.b--light-purple{border-color:#a463f2}.b--dark-pink{border-color:#d5008f}.b--hot-pink{border-color:#ff41b4}.b--pink{border-color:#ff80cc}.b--light-pink{border-color:#ffa3d7}.b--dark-green{border-color:#137752}.b--green{border-color:#19a974}.b--light-green{border-color:#9eebcf}.b--navy{border-color:#001b44}.b--dark-blue{border-color:#00449e}.b--blue{border-color:#357edd}.b--light-blue{border-color:#96ccff}.b--lightest-blue{border-color:#cdecff}.b--washed-blue{border-color:#f6fffe}.b--washed-green{border-color:#e8fdf5}.b--washed-yellow{border-color:#fffceb}.b--washed-red{border-color:#ffdfdf}.b--transparent{border-color:transparent}.b--inherit{border-color:inherit}.br0{border-radius:0}.br1{border-radius:.125rem}.br2{border-radius:.25rem}.br3{border-radius:.5rem}.br4{border-radius:1rem}.br-100{border-radius:100%}.br-pill{border-radius:9999px}.br--bottom{border-top-left-radius:0;border-top-right-radius:0}.br--top{border-bottom-right-radius:0}.br--right,.br--top{border-bottom-left-radius:0}.br--right{border-top-left-radius:0}.br--left{border-top-right-radius:0;border-bottom-right-radius:0}@media screen and (min-width:30em){.br0-ns{border-radius:0}.br1-ns{border-radius:.125rem}.br2-ns{border-radius:.25rem}.br3-ns{border-radius:.5rem}.br4-ns{border-radius:1rem}.br-100-ns{border-radius:100%}.br-pill-ns{border-radius:9999px}.br--bottom-ns{border-top-left-radius:0;border-top-right-radius:0}.br--top-ns{border-bottom-right-radius:0}.br--right-ns,.br--top-ns{border-bottom-left-radius:0}.br--right-ns{border-top-left-radius:0}.br--left-ns{border-top-right-radius:0;border-bottom-right-radius:0}}@media screen and (min-width:30em) and (max-width:60em){.br0-m{border-radius:0}.br1-m{border-radius:.125rem}.br2-m{border-radius:.25rem}.br3-m{border-radius:.5rem}.br4-m{border-radius:1rem}.br-100-m{border-radius:100%}.br-pill-m{border-radius:9999px}.br--bottom-m{border-top-left-radius:0;border-top-right-radius:0}.br--top-m{border-bottom-right-radius:0}.br--right-m,.br--top-m{border-bottom-left-radius:0}.br--right-m{border-top-left-radius:0}.br--left-m{border-top-right-radius:0;border-bottom-right-radius:0}}@media screen and (min-width:60em){.br0-l{border-radius:0}.br1-l{border-radius:.125rem}.br2-l{border-radius:.25rem}.br3-l{border-radius:.5rem}.br4-l{border-radius:1rem}.br-100-l{border-radius:100%}.br-pill-l{border-radius:9999px}.br--bottom-l{border-top-left-radius:0;border-top-right-radius:0}.br--top-l{border-bottom-right-radius:0}.br--right-l,.br--top-l{border-bottom-left-radius:0}.br--right-l{border-top-left-radius:0}.br--left-l{border-top-right-radius:0;border-bottom-right-radius:0}}.b--dotted{border-style:dotted}.b--dashed{border-style:dashed}.b--solid{border-style:solid}.b--none{border-style:none}@media screen and (min-width:30em){.b--dotted-ns{border-style:dotted}.b--dashed-ns{border-style:dashed}.b--solid-ns{border-style:solid}.b--none-ns{border-style:none}}@media screen and (min-width:30em) and (max-width:60em){.b--dotted-m{border-style:dotted}.b--dashed-m{border-style:dashed}.b--solid-m{border-style:solid}.b--none-m{border-style:none}}@media screen and (min-width:60em){.b--dotted-l{border-style:dotted}.b--dashed-l{border-style:dashed}.b--solid-l{border-style:solid}.b--none-l{border-style:none}}.bw0{border-width:0}.bw1{border-width:.125rem}.bw2{border-width:.25rem}.bw3{border-width:.5rem}.bw4{border-width:1rem}.bw5{border-width:2rem}.bt-0{border-top-width:0}.br-0{border-right-width:0}.bb-0{border-bottom-width:0}.bl-0{border-left-width:0}@media screen and (min-width:30em){.bw0-ns{border-width:0}.bw1-ns{border-width:.125rem}.bw2-ns{border-width:.25rem}.bw3-ns{border-width:.5rem}.bw4-ns{border-width:1rem}.bw5-ns{border-width:2rem}.bt-0-ns{border-top-width:0}.br-0-ns{border-right-width:0}.bb-0-ns{border-bottom-width:0}.bl-0-ns{border-left-width:0}}@media screen and (min-width:30em) and (max-width:60em){.bw0-m{border-width:0}.bw1-m{border-width:.125rem}.bw2-m{border-width:.25rem}.bw3-m{border-width:.5rem}.bw4-m{border-width:1rem}.bw5-m{border-width:2rem}.bt-0-m{border-top-width:0}.br-0-m{border-right-width:0}.bb-0-m{border-bottom-width:0}.bl-0-m{border-left-width:0}}@media screen and (min-width:60em){.bw0-l{border-width:0}.bw1-l{border-width:.125rem}.bw2-l{border-width:.25rem}.bw3-l{border-width:.5rem}.bw4-l{border-width:1rem}.bw5-l{border-width:2rem}.bt-0-l{border-top-width:0}.br-0-l{border-right-width:0}.bb-0-l{border-bottom-width:0}.bl-0-l{border-left-width:0}}.shadow-1{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.shadow-2{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.shadow-3{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.shadow-4{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.shadow-5{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}@media screen and (min-width:30em){.shadow-1-ns{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.shadow-2-ns{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.shadow-3-ns{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.shadow-4-ns{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.shadow-5-ns{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}}@media screen and (min-width:30em) and (max-width:60em){.shadow-1-m{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.shadow-2-m{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.shadow-3-m{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.shadow-4-m{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.shadow-5-m{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}}@media screen and (min-width:60em){.shadow-1-l{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.shadow-2-l{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.shadow-3-l{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.shadow-4-l{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.shadow-5-l{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}}.pre{overflow-x:auto;overflow-y:hidden;overflow:scroll}.top-0{top:0}.right-0{right:0}.bottom-0{bottom:0}.left-0{left:0}.top-1{top:1rem}.right-1{right:1rem}.bottom-1{bottom:1rem}.left-1{left:1rem}.top-2{top:2rem}.right-2{right:2rem}.bottom-2{bottom:2rem}.left-2{left:2rem}.top--1{top:-1rem}.right--1{right:-1rem}.bottom--1{bottom:-1rem}.left--1{left:-1rem}.top--2{top:-2rem}.right--2{right:-2rem}.bottom--2{bottom:-2rem}.left--2{left:-2rem}.absolute--fill{top:0;right:0;bottom:0;left:0}@media screen and (min-width:30em){.top-0-ns{top:0}.left-0-ns{left:0}.right-0-ns{right:0}.bottom-0-ns{bottom:0}.top-1-ns{top:1rem}.left-1-ns{left:1rem}.right-1-ns{right:1rem}.bottom-1-ns{bottom:1rem}.top-2-ns{top:2rem}.left-2-ns{left:2rem}.right-2-ns{right:2rem}.bottom-2-ns{bottom:2rem}.top--1-ns{top:-1rem}.right--1-ns{right:-1rem}.bottom--1-ns{bottom:-1rem}.left--1-ns{left:-1rem}.top--2-ns{top:-2rem}.right--2-ns{right:-2rem}.bottom--2-ns{bottom:-2rem}.left--2-ns{left:-2rem}.absolute--fill-ns{top:0;right:0;bottom:0;left:0}}@media screen and (min-width:30em) and (max-width:60em){.top-0-m{top:0}.left-0-m{left:0}.right-0-m{right:0}.bottom-0-m{bottom:0}.top-1-m{top:1rem}.left-1-m{left:1rem}.right-1-m{right:1rem}.bottom-1-m{bottom:1rem}.top-2-m{top:2rem}.left-2-m{left:2rem}.right-2-m{right:2rem}.bottom-2-m{bottom:2rem}.top--1-m{top:-1rem}.right--1-m{right:-1rem}.bottom--1-m{bottom:-1rem}.left--1-m{left:-1rem}.top--2-m{top:-2rem}.right--2-m{right:-2rem}.bottom--2-m{bottom:-2rem}.left--2-m{left:-2rem}.absolute--fill-m{top:0;right:0;bottom:0;left:0}}@media screen and (min-width:60em){.top-0-l{top:0}.left-0-l{left:0}.right-0-l{right:0}.bottom-0-l{bottom:0}.top-1-l{top:1rem}.left-1-l{left:1rem}.right-1-l{right:1rem}.bottom-1-l{bottom:1rem}.top-2-l{top:2rem}.left-2-l{left:2rem}.right-2-l{right:2rem}.bottom-2-l{bottom:2rem}.top--1-l{top:-1rem}.right--1-l{right:-1rem}.bottom--1-l{bottom:-1rem}.left--1-l{left:-1rem}.top--2-l{top:-2rem}.right--2-l{right:-2rem}.bottom--2-l{bottom:-2rem}.left--2-l{left:-2rem}.absolute--fill-l{top:0;right:0;bottom:0;left:0}}.cf:after,.cf:before{content:" ";display:table}.cf:after{clear:both}.cf{*zoom:1}.cl{clear:left}.cr{clear:right}.cb{clear:both}.cn{clear:none}@media screen and (min-width:30em){.cl-ns{clear:left}.cr-ns{clear:right}.cb-ns{clear:both}.cn-ns{clear:none}}@media screen and (min-width:30em) and (max-width:60em){.cl-m{clear:left}.cr-m{clear:right}.cb-m{clear:both}.cn-m{clear:none}}@media screen and (min-width:60em){.cl-l{clear:left}.cr-l{clear:right}.cb-l{clear:both}.cn-l{clear:none}}.dn{display:none}.di{display:inline}.db{display:block}.dib{display:inline-block}.dit{display:inline-table}.dt{display:table}.dtc{display:table-cell}.dt-row{display:table-row}.dt-row-group{display:table-row-group}.dt-column{display:table-column}.dt-column-group{display:table-column-group}.dt--fixed{table-layout:fixed;width:100%}@media screen and (min-width:30em){.dn-ns{display:none}.di-ns{display:inline}.db-ns{display:block}.dib-ns{display:inline-block}.dit-ns{display:inline-table}.dt-ns{display:table}.dtc-ns{display:table-cell}.dt-row-ns{display:table-row}.dt-row-group-ns{display:table-row-group}.dt-column-ns{display:table-column}.dt-column-group-ns{display:table-column-group}.dt--fixed-ns{table-layout:fixed;width:100%}}@media screen and (min-width:30em) and (max-width:60em){.dn-m{display:none}.di-m{display:inline}.db-m{display:block}.dib-m{display:inline-block}.dit-m{display:inline-table}.dt-m{display:table}.dtc-m{display:table-cell}.dt-row-m{display:table-row}.dt-row-group-m{display:table-row-group}.dt-column-m{display:table-column}.dt-column-group-m{display:table-column-group}.dt--fixed-m{table-layout:fixed;width:100%}}@media screen and (min-width:60em){.dn-l{display:none}.di-l{display:inline}.db-l{display:block}.dib-l{display:inline-block}.dit-l{display:inline-table}.dt-l{display:table}.dtc-l{display:table-cell}.dt-row-l{display:table-row}.dt-row-group-l{display:table-row-group}.dt-column-l{display:table-column}.dt-column-group-l{display:table-column-group}.dt--fixed-l{table-layout:fixed;width:100%}}.flex{display:-ms-flexbox;display:flex}.inline-flex{display:-ms-inline-flexbox;display:inline-flex}.flex-auto{-ms-flex:1 1 auto;flex:1 1 auto;min-width:0;min-height:0}.flex-none{-ms-flex:none;flex:none}.flex-column{-ms-flex-direction:column;flex-direction:column}.flex-row{-ms-flex-direction:row;flex-direction:row}.flex-wrap{-ms-flex-wrap:wrap;flex-wrap:wrap}.flex-nowrap{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse;flex-wrap:wrap-reverse}.flex-column-reverse{-ms-flex-direction:column-reverse;flex-direction:column-reverse}.flex-row-reverse{-ms-flex-direction:row-reverse;flex-direction:row-reverse}.items-start{-ms-flex-align:start;align-items:flex-start}.items-end{-ms-flex-align:end;align-items:flex-end}.items-center{-ms-flex-align:center;align-items:center}.items-baseline{-ms-flex-align:baseline;align-items:baseline}.items-stretch{-ms-flex-align:stretch;align-items:stretch}.self-start{-ms-flex-item-align:start;align-self:flex-start}.self-end{-ms-flex-item-align:end;align-self:flex-end}.self-center{-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}.self-baseline{-ms-flex-item-align:baseline;align-self:baseline}.self-stretch{-ms-flex-item-align:stretch;-ms-grid-row-align:stretch;align-self:stretch}.justify-start{-ms-flex-pack:start;justify-content:flex-start}.justify-end{-ms-flex-pack:end;justify-content:flex-end}.justify-center{-ms-flex-pack:center;justify-content:center}.justify-between{-ms-flex-pack:justify;justify-content:space-between}.justify-around{-ms-flex-pack:distribute;justify-content:space-around}.content-start{-ms-flex-line-pack:start;align-content:flex-start}.content-end{-ms-flex-line-pack:end;align-content:flex-end}.content-center{-ms-flex-line-pack:center;align-content:center}.content-between{-ms-flex-line-pack:justify;align-content:space-between}.content-around{-ms-flex-line-pack:distribute;align-content:space-around}.content-stretch{-ms-flex-line-pack:stretch;align-content:stretch}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-last{-ms-flex-order:99999;order:99999}.flex-grow-0{-ms-flex-positive:0;flex-grow:0}.flex-grow-1{-ms-flex-positive:1;flex-grow:1}.flex-shrink-0{-ms-flex-negative:0;flex-shrink:0}.flex-shrink-1{-ms-flex-negative:1;flex-shrink:1}@media screen and (min-width:30em){.flex-ns{display:-ms-flexbox;display:flex}.inline-flex-ns{display:-ms-inline-flexbox;display:inline-flex}.flex-auto-ns{-ms-flex:1 1 auto;flex:1 1 auto;min-width:0;min-height:0}.flex-none-ns{-ms-flex:none;flex:none}.flex-column-ns{-ms-flex-direction:column;flex-direction:column}.flex-row-ns{-ms-flex-direction:row;flex-direction:row}.flex-wrap-ns{-ms-flex-wrap:wrap;flex-wrap:wrap}.flex-nowrap-ns{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.flex-wrap-reverse-ns{-ms-flex-wrap:wrap-reverse;flex-wrap:wrap-reverse}.flex-column-reverse-ns{-ms-flex-direction:column-reverse;flex-direction:column-reverse}.flex-row-reverse-ns{-ms-flex-direction:row-reverse;flex-direction:row-reverse}.items-start-ns{-ms-flex-align:start;align-items:flex-start}.items-end-ns{-ms-flex-align:end;align-items:flex-end}.items-center-ns{-ms-flex-align:center;align-items:center}.items-baseline-ns{-ms-flex-align:baseline;align-items:baseline}.items-stretch-ns{-ms-flex-align:stretch;align-items:stretch}.self-start-ns{-ms-flex-item-align:start;align-self:flex-start}.self-end-ns{-ms-flex-item-align:end;align-self:flex-end}.self-center-ns{-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}.self-baseline-ns{-ms-flex-item-align:baseline;align-self:baseline}.self-stretch-ns{-ms-flex-item-align:stretch;-ms-grid-row-align:stretch;align-self:stretch}.justify-start-ns{-ms-flex-pack:start;justify-content:flex-start}.justify-end-ns{-ms-flex-pack:end;justify-content:flex-end}.justify-center-ns{-ms-flex-pack:center;justify-content:center}.justify-between-ns{-ms-flex-pack:justify;justify-content:space-between}.justify-around-ns{-ms-flex-pack:distribute;justify-content:space-around}.content-start-ns{-ms-flex-line-pack:start;align-content:flex-start}.content-end-ns{-ms-flex-line-pack:end;align-content:flex-end}.content-center-ns{-ms-flex-line-pack:center;align-content:center}.content-between-ns{-ms-flex-line-pack:justify;align-content:space-between}.content-around-ns{-ms-flex-line-pack:distribute;align-content:space-around}.content-stretch-ns{-ms-flex-line-pack:stretch;align-content:stretch}.order-0-ns{-ms-flex-order:0;order:0}.order-1-ns{-ms-flex-order:1;order:1}.order-2-ns{-ms-flex-order:2;order:2}.order-3-ns{-ms-flex-order:3;order:3}.order-4-ns{-ms-flex-order:4;order:4}.order-5-ns{-ms-flex-order:5;order:5}.order-6-ns{-ms-flex-order:6;order:6}.order-7-ns{-ms-flex-order:7;order:7}.order-8-ns{-ms-flex-order:8;order:8}.order-last-ns{-ms-flex-order:99999;order:99999}.flex-grow-0-ns{-ms-flex-positive:0;flex-grow:0}.flex-grow-1-ns{-ms-flex-positive:1;flex-grow:1}.flex-shrink-0-ns{-ms-flex-negative:0;flex-shrink:0}.flex-shrink-1-ns{-ms-flex-negative:1;flex-shrink:1}}@media screen and (min-width:30em) and (max-width:60em){.flex-m{display:-ms-flexbox;display:flex}.inline-flex-m{display:-ms-inline-flexbox;display:inline-flex}.flex-auto-m{-ms-flex:1 1 auto;flex:1 1 auto;min-width:0;min-height:0}.flex-none-m{-ms-flex:none;flex:none}.flex-column-m{-ms-flex-direction:column;flex-direction:column}.flex-row-m{-ms-flex-direction:row;flex-direction:row}.flex-wrap-m{-ms-flex-wrap:wrap;flex-wrap:wrap}.flex-nowrap-m{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.flex-wrap-reverse-m{-ms-flex-wrap:wrap-reverse;flex-wrap:wrap-reverse}.flex-column-reverse-m{-ms-flex-direction:column-reverse;flex-direction:column-reverse}.flex-row-reverse-m{-ms-flex-direction:row-reverse;flex-direction:row-reverse}.items-start-m{-ms-flex-align:start;align-items:flex-start}.items-end-m{-ms-flex-align:end;align-items:flex-end}.items-center-m{-ms-flex-align:center;align-items:center}.items-baseline-m{-ms-flex-align:baseline;align-items:baseline}.items-stretch-m{-ms-flex-align:stretch;align-items:stretch}.self-start-m{-ms-flex-item-align:start;align-self:flex-start}.self-end-m{-ms-flex-item-align:end;align-self:flex-end}.self-center-m{-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}.self-baseline-m{-ms-flex-item-align:baseline;align-self:baseline}.self-stretch-m{-ms-flex-item-align:stretch;-ms-grid-row-align:stretch;align-self:stretch}.justify-start-m{-ms-flex-pack:start;justify-content:flex-start}.justify-end-m{-ms-flex-pack:end;justify-content:flex-end}.justify-center-m{-ms-flex-pack:center;justify-content:center}.justify-between-m{-ms-flex-pack:justify;justify-content:space-between}.justify-around-m{-ms-flex-pack:distribute;justify-content:space-around}.content-start-m{-ms-flex-line-pack:start;align-content:flex-start}.content-end-m{-ms-flex-line-pack:end;align-content:flex-end}.content-center-m{-ms-flex-line-pack:center;align-content:center}.content-between-m{-ms-flex-line-pack:justify;align-content:space-between}.content-around-m{-ms-flex-line-pack:distribute;align-content:space-around}.content-stretch-m{-ms-flex-line-pack:stretch;align-content:stretch}.order-0-m{-ms-flex-order:0;order:0}.order-1-m{-ms-flex-order:1;order:1}.order-2-m{-ms-flex-order:2;order:2}.order-3-m{-ms-flex-order:3;order:3}.order-4-m{-ms-flex-order:4;order:4}.order-5-m{-ms-flex-order:5;order:5}.order-6-m{-ms-flex-order:6;order:6}.order-7-m{-ms-flex-order:7;order:7}.order-8-m{-ms-flex-order:8;order:8}.order-last-m{-ms-flex-order:99999;order:99999}.flex-grow-0-m{-ms-flex-positive:0;flex-grow:0}.flex-grow-1-m{-ms-flex-positive:1;flex-grow:1}.flex-shrink-0-m{-ms-flex-negative:0;flex-shrink:0}.flex-shrink-1-m{-ms-flex-negative:1;flex-shrink:1}}@media screen and (min-width:60em){.flex-l{display:-ms-flexbox;display:flex}.inline-flex-l{display:-ms-inline-flexbox;display:inline-flex}.flex-auto-l{-ms-flex:1 1 auto;flex:1 1 auto;min-width:0;min-height:0}.flex-none-l{-ms-flex:none;flex:none}.flex-column-l{-ms-flex-direction:column;flex-direction:column}.flex-row-l{-ms-flex-direction:row;flex-direction:row}.flex-wrap-l{-ms-flex-wrap:wrap;flex-wrap:wrap}.flex-nowrap-l{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.flex-wrap-reverse-l{-ms-flex-wrap:wrap-reverse;flex-wrap:wrap-reverse}.flex-column-reverse-l{-ms-flex-direction:column-reverse;flex-direction:column-reverse}.flex-row-reverse-l{-ms-flex-direction:row-reverse;flex-direction:row-reverse}.items-start-l{-ms-flex-align:start;align-items:flex-start}.items-end-l{-ms-flex-align:end;align-items:flex-end}.items-center-l{-ms-flex-align:center;align-items:center}.items-baseline-l{-ms-flex-align:baseline;align-items:baseline}.items-stretch-l{-ms-flex-align:stretch;align-items:stretch}.self-start-l{-ms-flex-item-align:start;align-self:flex-start}.self-end-l{-ms-flex-item-align:end;align-self:flex-end}.self-center-l{-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}.self-baseline-l{-ms-flex-item-align:baseline;align-self:baseline}.self-stretch-l{-ms-flex-item-align:stretch;-ms-grid-row-align:stretch;align-self:stretch}.justify-start-l{-ms-flex-pack:start;justify-content:flex-start}.justify-end-l{-ms-flex-pack:end;justify-content:flex-end}.justify-center-l{-ms-flex-pack:center;justify-content:center}.justify-between-l{-ms-flex-pack:justify;justify-content:space-between}.justify-around-l{-ms-flex-pack:distribute;justify-content:space-around}.content-start-l{-ms-flex-line-pack:start;align-content:flex-start}.content-end-l{-ms-flex-line-pack:end;align-content:flex-end}.content-center-l{-ms-flex-line-pack:center;align-content:center}.content-between-l{-ms-flex-line-pack:justify;align-content:space-between}.content-around-l{-ms-flex-line-pack:distribute;align-content:space-around}.content-stretch-l{-ms-flex-line-pack:stretch;align-content:stretch}.order-0-l{-ms-flex-order:0;order:0}.order-1-l{-ms-flex-order:1;order:1}.order-2-l{-ms-flex-order:2;order:2}.order-3-l{-ms-flex-order:3;order:3}.order-4-l{-ms-flex-order:4;order:4}.order-5-l{-ms-flex-order:5;order:5}.order-6-l{-ms-flex-order:6;order:6}.order-7-l{-ms-flex-order:7;order:7}.order-8-l{-ms-flex-order:8;order:8}.order-last-l{-ms-flex-order:99999;order:99999}.flex-grow-0-l{-ms-flex-positive:0;flex-grow:0}.flex-grow-1-l{-ms-flex-positive:1;flex-grow:1}.flex-shrink-0-l{-ms-flex-negative:0;flex-shrink:0}.flex-shrink-1-l{-ms-flex-negative:1;flex-shrink:1}}.fl{float:left}.fl,.fr{_display:inline}.fr{float:right}.fn{float:none}@media screen and (min-width:30em){.fl-ns{float:left}.fl-ns,.fr-ns{_display:inline}.fr-ns{float:right}.fn-ns{float:none}}@media screen and (min-width:30em) and (max-width:60em){.fl-m{float:left}.fl-m,.fr-m{_display:inline}.fr-m{float:right}.fn-m{float:none}}@media screen and (min-width:60em){.fl-l{float:left}.fl-l,.fr-l{_display:inline}.fr-l{float:right}.fn-l{float:none}}.sans-serif{font-family:-apple-system,BlinkMacSystemFont,avenir next,avenir,helvetica neue,helvetica,ubuntu,roboto,noto,segoe ui,arial,sans-serif}.serif{font-family:georgia,times,serif}.system-sans-serif{font-family:sans-serif}.system-serif{font-family:serif}.code,code{font-family:Consolas,monaco,monospace}.courier{font-family:Courier Next,courier,monospace}.helvetica{font-family:helvetica neue,helvetica,sans-serif}.avenir{font-family:avenir next,avenir,sans-serif}.athelas{font-family:athelas,georgia,serif}.georgia{font-family:georgia,serif}.times{font-family:times,serif}.bodoni{font-family:Bodoni MT,serif}.calisto{font-family:Calisto MT,serif}.garamond{font-family:garamond,serif}.baskerville{font-family:baskerville,serif}.i{font-style:italic}.fs-normal{font-style:normal}@media screen and (min-width:30em){.i-ns{font-style:italic}.fs-normal-ns{font-style:normal}}@media screen and (min-width:30em) and (max-width:60em){.i-m{font-style:italic}.fs-normal-m{font-style:normal}}@media screen and (min-width:60em){.i-l{font-style:italic}.fs-normal-l{font-style:normal}}.normal{font-weight:400}.b{font-weight:700}.fw1{font-weight:100}.fw2{font-weight:200}.fw3{font-weight:300}.fw4{font-weight:400}.fw5{font-weight:500}.fw6{font-weight:600}.fw7{font-weight:700}.fw8{font-weight:800}.fw9{font-weight:900}@media screen and (min-width:30em){.normal-ns{font-weight:400}.b-ns{font-weight:700}.fw1-ns{font-weight:100}.fw2-ns{font-weight:200}.fw3-ns{font-weight:300}.fw4-ns{font-weight:400}.fw5-ns{font-weight:500}.fw6-ns{font-weight:600}.fw7-ns{font-weight:700}.fw8-ns{font-weight:800}.fw9-ns{font-weight:900}}@media screen and (min-width:30em) and (max-width:60em){.normal-m{font-weight:400}.b-m{font-weight:700}.fw1-m{font-weight:100}.fw2-m{font-weight:200}.fw3-m{font-weight:300}.fw4-m{font-weight:400}.fw5-m{font-weight:500}.fw6-m{font-weight:600}.fw7-m{font-weight:700}.fw8-m{font-weight:800}.fw9-m{font-weight:900}}@media screen and (min-width:60em){.normal-l{font-weight:400}.b-l{font-weight:700}.fw1-l{font-weight:100}.fw2-l{font-weight:200}.fw3-l{font-weight:300}.fw4-l{font-weight:400}.fw5-l{font-weight:500}.fw6-l{font-weight:600}.fw7-l{font-weight:700}.fw8-l{font-weight:800}.fw9-l{font-weight:900}}.input-reset{-webkit-appearance:none;-moz-appearance:none}.button-reset::-moz-focus-inner,.input-reset::-moz-focus-inner{border:0;padding:0}.h1{height:1rem}.h2{height:2rem}.h3{height:4rem}.h4{height:8rem}.h5{height:16rem}.h-25{height:25%}.h-50{height:50%}.h-75{height:75%}.h-100{height:100%}.min-h-100{min-height:100%}.vh-25{height:25vh}.vh-50{height:50vh}.vh-75{height:75vh}.vh-100{height:100vh}.min-vh-100{min-height:100vh}.h-auto{height:auto}.h-inherit{height:inherit}@media screen and (min-width:30em){.h1-ns{height:1rem}.h2-ns{height:2rem}.h3-ns{height:4rem}.h4-ns{height:8rem}.h5-ns{height:16rem}.h-25-ns{height:25%}.h-50-ns{height:50%}.h-75-ns{height:75%}.h-100-ns{height:100%}.min-h-100-ns{min-height:100%}.vh-25-ns{height:25vh}.vh-50-ns{height:50vh}.vh-75-ns{height:75vh}.vh-100-ns{height:100vh}.min-vh-100-ns{min-height:100vh}.h-auto-ns{height:auto}.h-inherit-ns{height:inherit}}@media screen and (min-width:30em) and (max-width:60em){.h1-m{height:1rem}.h2-m{height:2rem}.h3-m{height:4rem}.h4-m{height:8rem}.h5-m{height:16rem}.h-25-m{height:25%}.h-50-m{height:50%}.h-75-m{height:75%}.h-100-m{height:100%}.min-h-100-m{min-height:100%}.vh-25-m{height:25vh}.vh-50-m{height:50vh}.vh-75-m{height:75vh}.vh-100-m{height:100vh}.min-vh-100-m{min-height:100vh}.h-auto-m{height:auto}.h-inherit-m{height:inherit}}@media screen and (min-width:60em){.h1-l{height:1rem}.h2-l{height:2rem}.h3-l{height:4rem}.h4-l{height:8rem}.h5-l{height:16rem}.h-25-l{height:25%}.h-50-l{height:50%}.h-75-l{height:75%}.h-100-l{height:100%}.min-h-100-l{min-height:100%}.vh-25-l{height:25vh}.vh-50-l{height:50vh}.vh-75-l{height:75vh}.vh-100-l{height:100vh}.min-vh-100-l{min-height:100vh}.h-auto-l{height:auto}.h-inherit-l{height:inherit}}.tracked{letter-spacing:.1em}.tracked-tight{letter-spacing:-.05em}.tracked-mega{letter-spacing:.25em}@media screen and (min-width:30em){.tracked-ns{letter-spacing:.1em}.tracked-tight-ns{letter-spacing:-.05em}.tracked-mega-ns{letter-spacing:.25em}}@media screen and (min-width:30em) and (max-width:60em){.tracked-m{letter-spacing:.1em}.tracked-tight-m{letter-spacing:-.05em}.tracked-mega-m{letter-spacing:.25em}}@media screen and (min-width:60em){.tracked-l{letter-spacing:.1em}.tracked-tight-l{letter-spacing:-.05em}.tracked-mega-l{letter-spacing:.25em}}.lh-solid{line-height:1}.lh-title{line-height:1.25}.lh-copy{line-height:1.5}@media screen and (min-width:30em){.lh-solid-ns{line-height:1}.lh-title-ns{line-height:1.25}.lh-copy-ns{line-height:1.5}}@media screen and (min-width:30em) and (max-width:60em){.lh-solid-m{line-height:1}.lh-title-m{line-height:1.25}.lh-copy-m{line-height:1.5}}@media screen and (min-width:60em){.lh-solid-l{line-height:1}.lh-title-l{line-height:1.25}.lh-copy-l{line-height:1.5}}.link{text-decoration:none}.link,.link:active,.link:focus,.link:hover,.link:link,.link:visited{transition:color .15s ease-in}.link:focus{outline:1px dotted currentColor}.list{list-style-type:none}.mw-100{max-width:100%}.mw1{max-width:1rem}.mw2{max-width:2rem}.mw3{max-width:4rem}.mw4{max-width:8rem}.mw5{max-width:16rem}.mw6{max-width:32rem}.mw7{max-width:48rem}.mw8{max-width:64rem}.mw9{max-width:96rem}.mw-none{max-width:none}@media screen and (min-width:30em){.mw-100-ns{max-width:100%}.mw1-ns{max-width:1rem}.mw2-ns{max-width:2rem}.mw3-ns{max-width:4rem}.mw4-ns{max-width:8rem}.mw5-ns{max-width:16rem}.mw6-ns{max-width:32rem}.mw7-ns{max-width:48rem}.mw8-ns{max-width:64rem}.mw9-ns{max-width:96rem}.mw-none-ns{max-width:none}}@media screen and (min-width:30em) and (max-width:60em){.mw-100-m{max-width:100%}.mw1-m{max-width:1rem}.mw2-m{max-width:2rem}.mw3-m{max-width:4rem}.mw4-m{max-width:8rem}.mw5-m{max-width:16rem}.mw6-m{max-width:32rem}.mw7-m{max-width:48rem}.mw8-m{max-width:64rem}.mw9-m{max-width:96rem}.mw-none-m{max-width:none}}@media screen and (min-width:60em){.mw-100-l{max-width:100%}.mw1-l{max-width:1rem}.mw2-l{max-width:2rem}.mw3-l{max-width:4rem}.mw4-l{max-width:8rem}.mw5-l{max-width:16rem}.mw6-l{max-width:32rem}.mw7-l{max-width:48rem}.mw8-l{max-width:64rem}.mw9-l{max-width:96rem}.mw-none-l{max-width:none}}.w1{width:1rem}.w2{width:2rem}.w3{width:4rem}.w4{width:8rem}.w5{width:16rem}.w-10{width:10%}.w-20{width:20%}.w-25{width:25%}.w-30{width:30%}.w-33{width:33%}.w-34{width:34%}.w-40{width:40%}.w-50{width:50%}.w-60{width:60%}.w-70{width:70%}.w-75{width:75%}.w-80{width:80%}.w-90{width:90%}.w-100{width:100%}.w-third{width:33.33333%}.w-two-thirds{width:66.66667%}.w-auto{width:auto}@media screen and (min-width:30em){.w1-ns{width:1rem}.w2-ns{width:2rem}.w3-ns{width:4rem}.w4-ns{width:8rem}.w5-ns{width:16rem}.w-10-ns{width:10%}.w-20-ns{width:20%}.w-25-ns{width:25%}.w-30-ns{width:30%}.w-33-ns{width:33%}.w-34-ns{width:34%}.w-40-ns{width:40%}.w-50-ns{width:50%}.w-60-ns{width:60%}.w-70-ns{width:70%}.w-75-ns{width:75%}.w-80-ns{width:80%}.w-90-ns{width:90%}.w-100-ns{width:100%}.w-third-ns{width:33.33333%}.w-two-thirds-ns{width:66.66667%}.w-auto-ns{width:auto}}@media screen and (min-width:30em) and (max-width:60em){.w1-m{width:1rem}.w2-m{width:2rem}.w3-m{width:4rem}.w4-m{width:8rem}.w5-m{width:16rem}.w-10-m{width:10%}.w-20-m{width:20%}.w-25-m{width:25%}.w-30-m{width:30%}.w-33-m{width:33%}.w-34-m{width:34%}.w-40-m{width:40%}.w-50-m{width:50%}.w-60-m{width:60%}.w-70-m{width:70%}.w-75-m{width:75%}.w-80-m{width:80%}.w-90-m{width:90%}.w-100-m{width:100%}.w-third-m{width:33.33333%}.w-two-thirds-m{width:66.66667%}.w-auto-m{width:auto}}@media screen and (min-width:60em){.w1-l{width:1rem}.w2-l{width:2rem}.w3-l{width:4rem}.w4-l{width:8rem}.w5-l{width:16rem}.w-10-l{width:10%}.w-20-l{width:20%}.w-25-l{width:25%}.w-30-l{width:30%}.w-33-l{width:33%}.w-34-l{width:34%}.w-40-l{width:40%}.w-50-l{width:50%}.w-60-l{width:60%}.w-70-l{width:70%}.w-75-l{width:75%}.w-80-l{width:80%}.w-90-l{width:90%}.w-100-l{width:100%}.w-third-l{width:33.33333%}.w-two-thirds-l{width:66.66667%}.w-auto-l{width:auto}}.overflow-visible{overflow:visible}.overflow-hidden{overflow:hidden}.overflow-scroll{overflow:scroll}.overflow-auto{overflow:auto}.overflow-x-visible{overflow-x:visible}.overflow-x-hidden{overflow-x:hidden}.overflow-x-scroll{overflow-x:scroll}.overflow-x-auto{overflow-x:auto}.overflow-y-visible{overflow-y:visible}.overflow-y-hidden{overflow-y:hidden}.overflow-y-scroll{overflow-y:scroll}.overflow-y-auto{overflow-y:auto}@media screen and (min-width:30em){.overflow-visible-ns{overflow:visible}.overflow-hidden-ns{overflow:hidden}.overflow-scroll-ns{overflow:scroll}.overflow-auto-ns{overflow:auto}.overflow-x-visible-ns{overflow-x:visible}.overflow-x-hidden-ns{overflow-x:hidden}.overflow-x-scroll-ns{overflow-x:scroll}.overflow-x-auto-ns{overflow-x:auto}.overflow-y-visible-ns{overflow-y:visible}.overflow-y-hidden-ns{overflow-y:hidden}.overflow-y-scroll-ns{overflow-y:scroll}.overflow-y-auto-ns{overflow-y:auto}}@media screen and (min-width:30em) and (max-width:60em){.overflow-visible-m{overflow:visible}.overflow-hidden-m{overflow:hidden}.overflow-scroll-m{overflow:scroll}.overflow-auto-m{overflow:auto}.overflow-x-visible-m{overflow-x:visible}.overflow-x-hidden-m{overflow-x:hidden}.overflow-x-scroll-m{overflow-x:scroll}.overflow-x-auto-m{overflow-x:auto}.overflow-y-visible-m{overflow-y:visible}.overflow-y-hidden-m{overflow-y:hidden}.overflow-y-scroll-m{overflow-y:scroll}.overflow-y-auto-m{overflow-y:auto}}@media screen and (min-width:60em){.overflow-visible-l{overflow:visible}.overflow-hidden-l{overflow:hidden}.overflow-scroll-l{overflow:scroll}.overflow-auto-l{overflow:auto}.overflow-x-visible-l{overflow-x:visible}.overflow-x-hidden-l{overflow-x:hidden}.overflow-x-scroll-l{overflow-x:scroll}.overflow-x-auto-l{overflow-x:auto}.overflow-y-visible-l{overflow-y:visible}.overflow-y-hidden-l{overflow-y:hidden}.overflow-y-scroll-l{overflow-y:scroll}.overflow-y-auto-l{overflow-y:auto}}.static{position:static}.relative{position:relative}.absolute{position:absolute}.fixed{position:fixed}@media screen and (min-width:30em){.static-ns{position:static}.relative-ns{position:relative}.absolute-ns{position:absolute}.fixed-ns{position:fixed}}@media screen and (min-width:30em) and (max-width:60em){.static-m{position:static}.relative-m{position:relative}.absolute-m{position:absolute}.fixed-m{position:fixed}}@media screen and (min-width:60em){.static-l{position:static}.relative-l{position:relative}.absolute-l{position:absolute}.fixed-l{position:fixed}}.o-100{opacity:1}.o-90{opacity:.9}.o-80{opacity:.8}.o-70{opacity:.7}.o-60{opacity:.6}.o-50{opacity:.5}.o-40{opacity:.4}.o-30{opacity:.3}.o-20{opacity:.2}.o-10{opacity:.1}.o-05{opacity:.05}.o-025{opacity:.025}.o-0{opacity:0}.rotate-45{transform:rotate(45deg)}.rotate-90{transform:rotate(90deg)}.rotate-135{transform:rotate(135deg)}.rotate-180{transform:rotate(180deg)}.rotate-225{transform:rotate(225deg)}.rotate-270{transform:rotate(270deg)}.rotate-315{transform:rotate(315deg)}@media screen and (min-width:30em){.rotate-45-ns{transform:rotate(45deg)}.rotate-90-ns{transform:rotate(90deg)}.rotate-135-ns{transform:rotate(135deg)}.rotate-180-ns{transform:rotate(180deg)}.rotate-225-ns{transform:rotate(225deg)}.rotate-270-ns{transform:rotate(270deg)}.rotate-315-ns{transform:rotate(315deg)}}@media screen and (min-width:30em) and (max-width:60em){.rotate-45-m{transform:rotate(45deg)}.rotate-90-m{transform:rotate(90deg)}.rotate-135-m{transform:rotate(135deg)}.rotate-180-m{transform:rotate(180deg)}.rotate-225-m{transform:rotate(225deg)}.rotate-270-m{transform:rotate(270deg)}.rotate-315-m{transform:rotate(315deg)}}@media screen and (min-width:60em){.rotate-45-l{transform:rotate(45deg)}.rotate-90-l{transform:rotate(90deg)}.rotate-135-l{transform:rotate(135deg)}.rotate-180-l{transform:rotate(180deg)}.rotate-225-l{transform:rotate(225deg)}.rotate-270-l{transform:rotate(270deg)}.rotate-315-l{transform:rotate(315deg)}}.black-90{color:rgba(0,0,0,.9)}.black-80{color:rgba(0,0,0,.8)}.black-70{color:rgba(0,0,0,.7)}.black-60{color:rgba(0,0,0,.6)}.black-50{color:rgba(0,0,0,.5)}.black-40{color:rgba(0,0,0,.4)}.black-30{color:rgba(0,0,0,.3)}.black-20{color:rgba(0,0,0,.2)}.black-10{color:rgba(0,0,0,.1)}.black-05{color:rgba(0,0,0,.05)}.white-90{color:hsla(0,0%,100%,.9)}.white-80{color:hsla(0,0%,100%,.8)}.white-70{color:hsla(0,0%,100%,.7)}.white-60{color:hsla(0,0%,100%,.6)}.white-50{color:hsla(0,0%,100%,.5)}.white-40{color:hsla(0,0%,100%,.4)}.white-30{color:hsla(0,0%,100%,.3)}.white-20{color:hsla(0,0%,100%,.2)}.white-10{color:hsla(0,0%,100%,.1)}.black{color:#000}.near-black{color:#111}.dark-gray{color:#333}.mid-gray{color:#555}.gray{color:#777}.silver{color:#999}.light-silver{color:#aaa}.moon-gray{color:#ccc}.light-gray{color:#eee}.near-white{color:#f4f4f4}.white{color:#fff}.dark-red{color:#e7040f}.red{color:#ff4136}.light-red{color:#ff725c}.orange{color:#ff6300}.gold{color:#ffb700}.yellow{color:gold}.light-yellow{color:#fbf1a9}.purple{color:#5e2ca5}.light-purple{color:#a463f2}.dark-pink{color:#d5008f}.hot-pink{color:#ff41b4}.pink{color:#ff80cc}.light-pink{color:#ffa3d7}.dark-green{color:#137752}.green{color:#19a974}.light-green{color:#9eebcf}.navy{color:#001b44}.dark-blue{color:#00449e}.blue{color:#357edd}.light-blue{color:#96ccff}.lightest-blue{color:#cdecff}.washed-blue{color:#f6fffe}.washed-green{color:#e8fdf5}.washed-yellow{color:#fffceb}.washed-red{color:#ffdfdf}.color-inherit{color:inherit}.bg-black-90{background-color:rgba(0,0,0,.9)}.bg-black-80{background-color:rgba(0,0,0,.8)}.bg-black-70{background-color:rgba(0,0,0,.7)}.bg-black-60{background-color:rgba(0,0,0,.6)}.bg-black-50{background-color:rgba(0,0,0,.5)}.bg-black-40{background-color:rgba(0,0,0,.4)}.bg-black-30{background-color:rgba(0,0,0,.3)}.bg-black-20{background-color:rgba(0,0,0,.2)}.bg-black-10{background-color:rgba(0,0,0,.1)}.bg-black-05{background-color:rgba(0,0,0,.05)}.bg-white-90{background-color:hsla(0,0%,100%,.9)}.bg-white-80{background-color:hsla(0,0%,100%,.8)}.bg-white-70{background-color:hsla(0,0%,100%,.7)}.bg-white-60{background-color:hsla(0,0%,100%,.6)}.bg-white-50{background-color:hsla(0,0%,100%,.5)}.bg-white-40{background-color:hsla(0,0%,100%,.4)}.bg-white-30{background-color:hsla(0,0%,100%,.3)}.bg-white-20{background-color:hsla(0,0%,100%,.2)}.bg-white-10{background-color:hsla(0,0%,100%,.1)}.bg-black{background-color:#000}.bg-near-black{background-color:#111}.bg-dark-gray{background-color:#333}.bg-mid-gray{background-color:#555}.bg-gray{background-color:#777}.bg-silver{background-color:#999}.bg-light-silver{background-color:#aaa}.bg-moon-gray{background-color:#ccc}.bg-light-gray{background-color:#eee}.bg-near-white{background-color:#f4f4f4}.bg-white{background-color:#fff}.bg-transparent{background-color:transparent}.bg-dark-red{background-color:#e7040f}.bg-red{background-color:#ff4136}.bg-light-red{background-color:#ff725c}.bg-orange{background-color:#ff6300}.bg-gold{background-color:#ffb700}.bg-yellow{background-color:gold}.bg-light-yellow{background-color:#fbf1a9}.bg-purple{background-color:#5e2ca5}.bg-light-purple{background-color:#a463f2}.bg-dark-pink{background-color:#d5008f}.bg-hot-pink{background-color:#ff41b4}.bg-pink{background-color:#ff80cc}.bg-light-pink{background-color:#ffa3d7}.bg-dark-green{background-color:#137752}.bg-green{background-color:#19a974}.bg-light-green{background-color:#9eebcf}.bg-navy{background-color:#001b44}.bg-dark-blue{background-color:#00449e}.bg-blue{background-color:#357edd}.bg-light-blue{background-color:#96ccff}.bg-lightest-blue{background-color:#cdecff}.bg-washed-blue{background-color:#f6fffe}.bg-washed-green{background-color:#e8fdf5}.bg-washed-yellow{background-color:#fffceb}.bg-washed-red{background-color:#ffdfdf}.bg-inherit{background-color:inherit}.hover-black:focus,.hover-black:hover{color:#000}.hover-near-black:focus,.hover-near-black:hover{color:#111}.hover-dark-gray:focus,.hover-dark-gray:hover{color:#333}.hover-mid-gray:focus,.hover-mid-gray:hover{color:#555}.hover-gray:focus,.hover-gray:hover{color:#777}.hover-silver:focus,.hover-silver:hover{color:#999}.hover-light-silver:focus,.hover-light-silver:hover{color:#aaa}.hover-moon-gray:focus,.hover-moon-gray:hover{color:#ccc}.hover-light-gray:focus,.hover-light-gray:hover{color:#eee}.hover-near-white:focus,.hover-near-white:hover{color:#f4f4f4}.hover-white:focus,.hover-white:hover{color:#fff}.hover-black-90:focus,.hover-black-90:hover{color:rgba(0,0,0,.9)}.hover-black-80:focus,.hover-black-80:hover{color:rgba(0,0,0,.8)}.hover-black-70:focus,.hover-black-70:hover{color:rgba(0,0,0,.7)}.hover-black-60:focus,.hover-black-60:hover{color:rgba(0,0,0,.6)}.hover-black-50:focus,.hover-black-50:hover{color:rgba(0,0,0,.5)}.hover-black-40:focus,.hover-black-40:hover{color:rgba(0,0,0,.4)}.hover-black-30:focus,.hover-black-30:hover{color:rgba(0,0,0,.3)}.hover-black-20:focus,.hover-black-20:hover{color:rgba(0,0,0,.2)}.hover-black-10:focus,.hover-black-10:hover{color:rgba(0,0,0,.1)}.hover-white-90:focus,.hover-white-90:hover{color:hsla(0,0%,100%,.9)}.hover-white-80:focus,.hover-white-80:hover{color:hsla(0,0%,100%,.8)}.hover-white-70:focus,.hover-white-70:hover{color:hsla(0,0%,100%,.7)}.hover-white-60:focus,.hover-white-60:hover{color:hsla(0,0%,100%,.6)}.hover-white-50:focus,.hover-white-50:hover{color:hsla(0,0%,100%,.5)}.hover-white-40:focus,.hover-white-40:hover{color:hsla(0,0%,100%,.4)}.hover-white-30:focus,.hover-white-30:hover{color:hsla(0,0%,100%,.3)}.hover-white-20:focus,.hover-white-20:hover{color:hsla(0,0%,100%,.2)}.hover-white-10:focus,.hover-white-10:hover{color:hsla(0,0%,100%,.1)}.hover-inherit:focus,.hover-inherit:hover{color:inherit}.hover-bg-black:focus,.hover-bg-black:hover{background-color:#000}.hover-bg-near-black:focus,.hover-bg-near-black:hover{background-color:#111}.hover-bg-dark-gray:focus,.hover-bg-dark-gray:hover{background-color:#333}.hover-bg-mid-gray:focus,.hover-bg-mid-gray:hover{background-color:#555}.hover-bg-gray:focus,.hover-bg-gray:hover{background-color:#777}.hover-bg-silver:focus,.hover-bg-silver:hover{background-color:#999}.hover-bg-light-silver:focus,.hover-bg-light-silver:hover{background-color:#aaa}.hover-bg-moon-gray:focus,.hover-bg-moon-gray:hover{background-color:#ccc}.hover-bg-light-gray:focus,.hover-bg-light-gray:hover{background-color:#eee}.hover-bg-near-white:focus,.hover-bg-near-white:hover{background-color:#f4f4f4}.hover-bg-white:focus,.hover-bg-white:hover{background-color:#fff}.hover-bg-transparent:focus,.hover-bg-transparent:hover{background-color:transparent}.hover-bg-black-90:focus,.hover-bg-black-90:hover{background-color:rgba(0,0,0,.9)}.hover-bg-black-80:focus,.hover-bg-black-80:hover{background-color:rgba(0,0,0,.8)}.hover-bg-black-70:focus,.hover-bg-black-70:hover{background-color:rgba(0,0,0,.7)}.hover-bg-black-60:focus,.hover-bg-black-60:hover{background-color:rgba(0,0,0,.6)}.hover-bg-black-50:focus,.hover-bg-black-50:hover{background-color:rgba(0,0,0,.5)}.hover-bg-black-40:focus,.hover-bg-black-40:hover{background-color:rgba(0,0,0,.4)}.hover-bg-black-30:focus,.hover-bg-black-30:hover{background-color:rgba(0,0,0,.3)}.hover-bg-black-20:focus,.hover-bg-black-20:hover{background-color:rgba(0,0,0,.2)}.hover-bg-black-10:focus,.hover-bg-black-10:hover{background-color:rgba(0,0,0,.1)}.hover-bg-white-90:focus,.hover-bg-white-90:hover{background-color:hsla(0,0%,100%,.9)}.hover-bg-white-80:focus,.hover-bg-white-80:hover{background-color:hsla(0,0%,100%,.8)}.hover-bg-white-70:focus,.hover-bg-white-70:hover{background-color:hsla(0,0%,100%,.7)}.hover-bg-white-60:focus,.hover-bg-white-60:hover{background-color:hsla(0,0%,100%,.6)}.hover-bg-white-50:focus,.hover-bg-white-50:hover{background-color:hsla(0,0%,100%,.5)}.hover-bg-white-40:focus,.hover-bg-white-40:hover{background-color:hsla(0,0%,100%,.4)}.hover-bg-white-30:focus,.hover-bg-white-30:hover{background-color:hsla(0,0%,100%,.3)}.hover-bg-white-20:focus,.hover-bg-white-20:hover{background-color:hsla(0,0%,100%,.2)}.hover-bg-white-10:focus,.hover-bg-white-10:hover{background-color:hsla(0,0%,100%,.1)}.hover-dark-red:focus,.hover-dark-red:hover{color:#e7040f}.hover-red:focus,.hover-red:hover{color:#ff4136}.hover-light-red:focus,.hover-light-red:hover{color:#ff725c}.hover-orange:focus,.hover-orange:hover{color:#ff6300}.hover-gold:focus,.hover-gold:hover{color:#ffb700}.hover-yellow:focus,.hover-yellow:hover{color:gold}.hover-light-yellow:focus,.hover-light-yellow:hover{color:#fbf1a9}.hover-purple:focus,.hover-purple:hover{color:#5e2ca5}.hover-light-purple:focus,.hover-light-purple:hover{color:#a463f2}.hover-dark-pink:focus,.hover-dark-pink:hover{color:#d5008f}.hover-hot-pink:focus,.hover-hot-pink:hover{color:#ff41b4}.hover-pink:focus,.hover-pink:hover{color:#ff80cc}.hover-light-pink:focus,.hover-light-pink:hover{color:#ffa3d7}.hover-dark-green:focus,.hover-dark-green:hover{color:#137752}.hover-green:focus,.hover-green:hover{color:#19a974}.hover-light-green:focus,.hover-light-green:hover{color:#9eebcf}.hover-navy:focus,.hover-navy:hover{color:#001b44}.hover-dark-blue:focus,.hover-dark-blue:hover{color:#00449e}.hover-blue:focus,.hover-blue:hover{color:#357edd}.hover-light-blue:focus,.hover-light-blue:hover{color:#96ccff}.hover-lightest-blue:focus,.hover-lightest-blue:hover{color:#cdecff}.hover-washed-blue:focus,.hover-washed-blue:hover{color:#f6fffe}.hover-washed-green:focus,.hover-washed-green:hover{color:#e8fdf5}.hover-washed-yellow:focus,.hover-washed-yellow:hover{color:#fffceb}.hover-washed-red:focus,.hover-washed-red:hover{color:#ffdfdf}.hover-bg-dark-red:focus,.hover-bg-dark-red:hover{background-color:#e7040f}.hover-bg-red:focus,.hover-bg-red:hover{background-color:#ff4136}.hover-bg-light-red:focus,.hover-bg-light-red:hover{background-color:#ff725c}.hover-bg-orange:focus,.hover-bg-orange:hover{background-color:#ff6300}.hover-bg-gold:focus,.hover-bg-gold:hover{background-color:#ffb700}.hover-bg-yellow:focus,.hover-bg-yellow:hover{background-color:gold}.hover-bg-light-yellow:focus,.hover-bg-light-yellow:hover{background-color:#fbf1a9}.hover-bg-purple:focus,.hover-bg-purple:hover{background-color:#5e2ca5}.hover-bg-light-purple:focus,.hover-bg-light-purple:hover{background-color:#a463f2}.hover-bg-dark-pink:focus,.hover-bg-dark-pink:hover{background-color:#d5008f}.hover-bg-hot-pink:focus,.hover-bg-hot-pink:hover{background-color:#ff41b4}.hover-bg-pink:focus,.hover-bg-pink:hover{background-color:#ff80cc}.hover-bg-light-pink:focus,.hover-bg-light-pink:hover{background-color:#ffa3d7}.hover-bg-dark-green:focus,.hover-bg-dark-green:hover{background-color:#137752}.hover-bg-green:focus,.hover-bg-green:hover{background-color:#19a974}.hover-bg-light-green:focus,.hover-bg-light-green:hover{background-color:#9eebcf}.hover-bg-navy:focus,.hover-bg-navy:hover{background-color:#001b44}.hover-bg-dark-blue:focus,.hover-bg-dark-blue:hover{background-color:#00449e}.hover-bg-blue:focus,.hover-bg-blue:hover{background-color:#357edd}.hover-bg-light-blue:focus,.hover-bg-light-blue:hover{background-color:#96ccff}.hover-bg-lightest-blue:focus,.hover-bg-lightest-blue:hover{background-color:#cdecff}.hover-bg-washed-blue:focus,.hover-bg-washed-blue:hover{background-color:#f6fffe}.hover-bg-washed-green:focus,.hover-bg-washed-green:hover{background-color:#e8fdf5}.hover-bg-washed-yellow:focus,.hover-bg-washed-yellow:hover{background-color:#fffceb}.hover-bg-washed-red:focus,.hover-bg-washed-red:hover{background-color:#ffdfdf}.hover-bg-inherit:focus,.hover-bg-inherit:hover{background-color:inherit}.pa0{padding:0}.pa1{padding:.25rem}.pa2{padding:.5rem}.pa3{padding:1rem}.pa4{padding:2rem}.pa5{padding:4rem}.pa6{padding:8rem}.pa7{padding:16rem}.pl0{padding-left:0}.pl1{padding-left:.25rem}.pl2{padding-left:.5rem}.pl3{padding-left:1rem}.pl4{padding-left:2rem}.pl5{padding-left:4rem}.pl6{padding-left:8rem}.pl7{padding-left:16rem}.pr0{padding-right:0}.pr1{padding-right:.25rem}.pr2{padding-right:.5rem}.pr3{padding-right:1rem}.pr4{padding-right:2rem}.pr5{padding-right:4rem}.pr6{padding-right:8rem}.pr7{padding-right:16rem}.pb0{padding-bottom:0}.pb1{padding-bottom:.25rem}.pb2{padding-bottom:.5rem}.pb3{padding-bottom:1rem}.pb4{padding-bottom:2rem}.pb5{padding-bottom:4rem}.pb6{padding-bottom:8rem}.pb7{padding-bottom:16rem}.pt0{padding-top:0}.pt1{padding-top:.25rem}.pt2{padding-top:.5rem}.pt3{padding-top:1rem}.pt4{padding-top:2rem}.pt5{padding-top:4rem}.pt6{padding-top:8rem}.pt7{padding-top:16rem}.pv0{padding-top:0;padding-bottom:0}.pv1{padding-top:.25rem;padding-bottom:.25rem}.pv2{padding-top:.5rem;padding-bottom:.5rem}.pv3{padding-top:1rem;padding-bottom:1rem}.pv4{padding-top:2rem;padding-bottom:2rem}.pv5{padding-top:4rem;padding-bottom:4rem}.pv6{padding-top:8rem;padding-bottom:8rem}.pv7{padding-top:16rem;padding-bottom:16rem}.ph0{padding-left:0;padding-right:0}.ph1{padding-left:.25rem;padding-right:.25rem}.ph2{padding-left:.5rem;padding-right:.5rem}.ph3{padding-left:1rem;padding-right:1rem}.ph4{padding-left:2rem;padding-right:2rem}.ph5{padding-left:4rem;padding-right:4rem}.ph6{padding-left:8rem;padding-right:8rem}.ph7{padding-left:16rem;padding-right:16rem}.ma0{margin:0}.ma1{margin:.25rem}.ma2{margin:.5rem}.ma3{margin:1rem}.ma4{margin:2rem}.ma5{margin:4rem}.ma6{margin:8rem}.ma7{margin:16rem}.ml0{margin-left:0}.ml1{margin-left:.25rem}.ml2{margin-left:.5rem}.ml3{margin-left:1rem}.ml4{margin-left:2rem}.ml5{margin-left:4rem}.ml6{margin-left:8rem}.ml7{margin-left:16rem}.mr0{margin-right:0}.mr1{margin-right:.25rem}.mr2{margin-right:.5rem}.mr3{margin-right:1rem}.mr4{margin-right:2rem}.mr5{margin-right:4rem}.mr6{margin-right:8rem}.mr7{margin-right:16rem}.mb0{margin-bottom:0}.mb1{margin-bottom:.25rem}.mb2{margin-bottom:.5rem}.mb3{margin-bottom:1rem}.mb4{margin-bottom:2rem}.mb5{margin-bottom:4rem}.mb6{margin-bottom:8rem}.mb7{margin-bottom:16rem}.mt0{margin-top:0}.mt1{margin-top:.25rem}.mt2{margin-top:.5rem}.mt3{margin-top:1rem}.mt4{margin-top:2rem}.mt5{margin-top:4rem}.mt6{margin-top:8rem}.mt7{margin-top:16rem}.mv0{margin-top:0;margin-bottom:0}.mv1{margin-top:.25rem;margin-bottom:.25rem}.mv2{margin-top:.5rem;margin-bottom:.5rem}.mv3{margin-top:1rem;margin-bottom:1rem}.mv4{margin-top:2rem;margin-bottom:2rem}.mv5{margin-top:4rem;margin-bottom:4rem}.mv6{margin-top:8rem;margin-bottom:8rem}.mv7{margin-top:16rem;margin-bottom:16rem}.mh0{margin-left:0;margin-right:0}.mh1{margin-left:.25rem;margin-right:.25rem}.mh2{margin-left:.5rem;margin-right:.5rem}.mh3{margin-left:1rem;margin-right:1rem}.mh4{margin-left:2rem;margin-right:2rem}.mh5{margin-left:4rem;margin-right:4rem}.mh6{margin-left:8rem;margin-right:8rem}.mh7{margin-left:16rem;margin-right:16rem}@media screen and (min-width:30em){.pa0-ns{padding:0}.pa1-ns{padding:.25rem}.pa2-ns{padding:.5rem}.pa3-ns{padding:1rem}.pa4-ns{padding:2rem}.pa5-ns{padding:4rem}.pa6-ns{padding:8rem}.pa7-ns{padding:16rem}.pl0-ns{padding-left:0}.pl1-ns{padding-left:.25rem}.pl2-ns{padding-left:.5rem}.pl3-ns{padding-left:1rem}.pl4-ns{padding-left:2rem}.pl5-ns{padding-left:4rem}.pl6-ns{padding-left:8rem}.pl7-ns{padding-left:16rem}.pr0-ns{padding-right:0}.pr1-ns{padding-right:.25rem}.pr2-ns{padding-right:.5rem}.pr3-ns{padding-right:1rem}.pr4-ns{padding-right:2rem}.pr5-ns{padding-right:4rem}.pr6-ns{padding-right:8rem}.pr7-ns{padding-right:16rem}.pb0-ns{padding-bottom:0}.pb1-ns{padding-bottom:.25rem}.pb2-ns{padding-bottom:.5rem}.pb3-ns{padding-bottom:1rem}.pb4-ns{padding-bottom:2rem}.pb5-ns{padding-bottom:4rem}.pb6-ns{padding-bottom:8rem}.pb7-ns{padding-bottom:16rem}.pt0-ns{padding-top:0}.pt1-ns{padding-top:.25rem}.pt2-ns{padding-top:.5rem}.pt3-ns{padding-top:1rem}.pt4-ns{padding-top:2rem}.pt5-ns{padding-top:4rem}.pt6-ns{padding-top:8rem}.pt7-ns{padding-top:16rem}.pv0-ns{padding-top:0;padding-bottom:0}.pv1-ns{padding-top:.25rem;padding-bottom:.25rem}.pv2-ns{padding-top:.5rem;padding-bottom:.5rem}.pv3-ns{padding-top:1rem;padding-bottom:1rem}.pv4-ns{padding-top:2rem;padding-bottom:2rem}.pv5-ns{padding-top:4rem;padding-bottom:4rem}.pv6-ns{padding-top:8rem;padding-bottom:8rem}.pv7-ns{padding-top:16rem;padding-bottom:16rem}.ph0-ns{padding-left:0;padding-right:0}.ph1-ns{padding-left:.25rem;padding-right:.25rem}.ph2-ns{padding-left:.5rem;padding-right:.5rem}.ph3-ns{padding-left:1rem;padding-right:1rem}.ph4-ns{padding-left:2rem;padding-right:2rem}.ph5-ns{padding-left:4rem;padding-right:4rem}.ph6-ns{padding-left:8rem;padding-right:8rem}.ph7-ns{padding-left:16rem;padding-right:16rem}.ma0-ns{margin:0}.ma1-ns{margin:.25rem}.ma2-ns{margin:.5rem}.ma3-ns{margin:1rem}.ma4-ns{margin:2rem}.ma5-ns{margin:4rem}.ma6-ns{margin:8rem}.ma7-ns{margin:16rem}.ml0-ns{margin-left:0}.ml1-ns{margin-left:.25rem}.ml2-ns{margin-left:.5rem}.ml3-ns{margin-left:1rem}.ml4-ns{margin-left:2rem}.ml5-ns{margin-left:4rem}.ml6-ns{margin-left:8rem}.ml7-ns{margin-left:16rem}.mr0-ns{margin-right:0}.mr1-ns{margin-right:.25rem}.mr2-ns{margin-right:.5rem}.mr3-ns{margin-right:1rem}.mr4-ns{margin-right:2rem}.mr5-ns{margin-right:4rem}.mr6-ns{margin-right:8rem}.mr7-ns{margin-right:16rem}.mb0-ns{margin-bottom:0}.mb1-ns{margin-bottom:.25rem}.mb2-ns{margin-bottom:.5rem}.mb3-ns{margin-bottom:1rem}.mb4-ns{margin-bottom:2rem}.mb5-ns{margin-bottom:4rem}.mb6-ns{margin-bottom:8rem}.mb7-ns{margin-bottom:16rem}.mt0-ns{margin-top:0}.mt1-ns{margin-top:.25rem}.mt2-ns{margin-top:.5rem}.mt3-ns{margin-top:1rem}.mt4-ns{margin-top:2rem}.mt5-ns{margin-top:4rem}.mt6-ns{margin-top:8rem}.mt7-ns{margin-top:16rem}.mv0-ns{margin-top:0;margin-bottom:0}.mv1-ns{margin-top:.25rem;margin-bottom:.25rem}.mv2-ns{margin-top:.5rem;margin-bottom:.5rem}.mv3-ns{margin-top:1rem;margin-bottom:1rem}.mv4-ns{margin-top:2rem;margin-bottom:2rem}.mv5-ns{margin-top:4rem;margin-bottom:4rem}.mv6-ns{margin-top:8rem;margin-bottom:8rem}.mv7-ns{margin-top:16rem;margin-bottom:16rem}.mh0-ns{margin-left:0;margin-right:0}.mh1-ns{margin-left:.25rem;margin-right:.25rem}.mh2-ns{margin-left:.5rem;margin-right:.5rem}.mh3-ns{margin-left:1rem;margin-right:1rem}.mh4-ns{margin-left:2rem;margin-right:2rem}.mh5-ns{margin-left:4rem;margin-right:4rem}.mh6-ns{margin-left:8rem;margin-right:8rem}.mh7-ns{margin-left:16rem;margin-right:16rem}}@media screen and (min-width:30em) and (max-width:60em){.pa0-m{padding:0}.pa1-m{padding:.25rem}.pa2-m{padding:.5rem}.pa3-m{padding:1rem}.pa4-m{padding:2rem}.pa5-m{padding:4rem}.pa6-m{padding:8rem}.pa7-m{padding:16rem}.pl0-m{padding-left:0}.pl1-m{padding-left:.25rem}.pl2-m{padding-left:.5rem}.pl3-m{padding-left:1rem}.pl4-m{padding-left:2rem}.pl5-m{padding-left:4rem}.pl6-m{padding-left:8rem}.pl7-m{padding-left:16rem}.pr0-m{padding-right:0}.pr1-m{padding-right:.25rem}.pr2-m{padding-right:.5rem}.pr3-m{padding-right:1rem}.pr4-m{padding-right:2rem}.pr5-m{padding-right:4rem}.pr6-m{padding-right:8rem}.pr7-m{padding-right:16rem}.pb0-m{padding-bottom:0}.pb1-m{padding-bottom:.25rem}.pb2-m{padding-bottom:.5rem}.pb3-m{padding-bottom:1rem}.pb4-m{padding-bottom:2rem}.pb5-m{padding-bottom:4rem}.pb6-m{padding-bottom:8rem}.pb7-m{padding-bottom:16rem}.pt0-m{padding-top:0}.pt1-m{padding-top:.25rem}.pt2-m{padding-top:.5rem}.pt3-m{padding-top:1rem}.pt4-m{padding-top:2rem}.pt5-m{padding-top:4rem}.pt6-m{padding-top:8rem}.pt7-m{padding-top:16rem}.pv0-m{padding-top:0;padding-bottom:0}.pv1-m{padding-top:.25rem;padding-bottom:.25rem}.pv2-m{padding-top:.5rem;padding-bottom:.5rem}.pv3-m{padding-top:1rem;padding-bottom:1rem}.pv4-m{padding-top:2rem;padding-bottom:2rem}.pv5-m{padding-top:4rem;padding-bottom:4rem}.pv6-m{padding-top:8rem;padding-bottom:8rem}.pv7-m{padding-top:16rem;padding-bottom:16rem}.ph0-m{padding-left:0;padding-right:0}.ph1-m{padding-left:.25rem;padding-right:.25rem}.ph2-m{padding-left:.5rem;padding-right:.5rem}.ph3-m{padding-left:1rem;padding-right:1rem}.ph4-m{padding-left:2rem;padding-right:2rem}.ph5-m{padding-left:4rem;padding-right:4rem}.ph6-m{padding-left:8rem;padding-right:8rem}.ph7-m{padding-left:16rem;padding-right:16rem}.ma0-m{margin:0}.ma1-m{margin:.25rem}.ma2-m{margin:.5rem}.ma3-m{margin:1rem}.ma4-m{margin:2rem}.ma5-m{margin:4rem}.ma6-m{margin:8rem}.ma7-m{margin:16rem}.ml0-m{margin-left:0}.ml1-m{margin-left:.25rem}.ml2-m{margin-left:.5rem}.ml3-m{margin-left:1rem}.ml4-m{margin-left:2rem}.ml5-m{margin-left:4rem}.ml6-m{margin-left:8rem}.ml7-m{margin-left:16rem}.mr0-m{margin-right:0}.mr1-m{margin-right:.25rem}.mr2-m{margin-right:.5rem}.mr3-m{margin-right:1rem}.mr4-m{margin-right:2rem}.mr5-m{margin-right:4rem}.mr6-m{margin-right:8rem}.mr7-m{margin-right:16rem}.mb0-m{margin-bottom:0}.mb1-m{margin-bottom:.25rem}.mb2-m{margin-bottom:.5rem}.mb3-m{margin-bottom:1rem}.mb4-m{margin-bottom:2rem}.mb5-m{margin-bottom:4rem}.mb6-m{margin-bottom:8rem}.mb7-m{margin-bottom:16rem}.mt0-m{margin-top:0}.mt1-m{margin-top:.25rem}.mt2-m{margin-top:.5rem}.mt3-m{margin-top:1rem}.mt4-m{margin-top:2rem}.mt5-m{margin-top:4rem}.mt6-m{margin-top:8rem}.mt7-m{margin-top:16rem}.mv0-m{margin-top:0;margin-bottom:0}.mv1-m{margin-top:.25rem;margin-bottom:.25rem}.mv2-m{margin-top:.5rem;margin-bottom:.5rem}.mv3-m{margin-top:1rem;margin-bottom:1rem}.mv4-m{margin-top:2rem;margin-bottom:2rem}.mv5-m{margin-top:4rem;margin-bottom:4rem}.mv6-m{margin-top:8rem;margin-bottom:8rem}.mv7-m{margin-top:16rem;margin-bottom:16rem}.mh0-m{margin-left:0;margin-right:0}.mh1-m{margin-left:.25rem;margin-right:.25rem}.mh2-m{margin-left:.5rem;margin-right:.5rem}.mh3-m{margin-left:1rem;margin-right:1rem}.mh4-m{margin-left:2rem;margin-right:2rem}.mh5-m{margin-left:4rem;margin-right:4rem}.mh6-m{margin-left:8rem;margin-right:8rem}.mh7-m{margin-left:16rem;margin-right:16rem}}@media screen and (min-width:60em){.pa0-l{padding:0}.pa1-l{padding:.25rem}.pa2-l{padding:.5rem}.pa3-l{padding:1rem}.pa4-l{padding:2rem}.pa5-l{padding:4rem}.pa6-l{padding:8rem}.pa7-l{padding:16rem}.pl0-l{padding-left:0}.pl1-l{padding-left:.25rem}.pl2-l{padding-left:.5rem}.pl3-l{padding-left:1rem}.pl4-l{padding-left:2rem}.pl5-l{padding-left:4rem}.pl6-l{padding-left:8rem}.pl7-l{padding-left:16rem}.pr0-l{padding-right:0}.pr1-l{padding-right:.25rem}.pr2-l{padding-right:.5rem}.pr3-l{padding-right:1rem}.pr4-l{padding-right:2rem}.pr5-l{padding-right:4rem}.pr6-l{padding-right:8rem}.pr7-l{padding-right:16rem}.pb0-l{padding-bottom:0}.pb1-l{padding-bottom:.25rem}.pb2-l{padding-bottom:.5rem}.pb3-l{padding-bottom:1rem}.pb4-l{padding-bottom:2rem}.pb5-l{padding-bottom:4rem}.pb6-l{padding-bottom:8rem}.pb7-l{padding-bottom:16rem}.pt0-l{padding-top:0}.pt1-l{padding-top:.25rem}.pt2-l{padding-top:.5rem}.pt3-l{padding-top:1rem}.pt4-l{padding-top:2rem}.pt5-l{padding-top:4rem}.pt6-l{padding-top:8rem}.pt7-l{padding-top:16rem}.pv0-l{padding-top:0;padding-bottom:0}.pv1-l{padding-top:.25rem;padding-bottom:.25rem}.pv2-l{padding-top:.5rem;padding-bottom:.5rem}.pv3-l{padding-top:1rem;padding-bottom:1rem}.pv4-l{padding-top:2rem;padding-bottom:2rem}.pv5-l{padding-top:4rem;padding-bottom:4rem}.pv6-l{padding-top:8rem;padding-bottom:8rem}.pv7-l{padding-top:16rem;padding-bottom:16rem}.ph0-l{padding-left:0;padding-right:0}.ph1-l{padding-left:.25rem;padding-right:.25rem}.ph2-l{padding-left:.5rem;padding-right:.5rem}.ph3-l{padding-left:1rem;padding-right:1rem}.ph4-l{padding-left:2rem;padding-right:2rem}.ph5-l{padding-left:4rem;padding-right:4rem}.ph6-l{padding-left:8rem;padding-right:8rem}.ph7-l{padding-left:16rem;padding-right:16rem}.ma0-l{margin:0}.ma1-l{margin:.25rem}.ma2-l{margin:.5rem}.ma3-l{margin:1rem}.ma4-l{margin:2rem}.ma5-l{margin:4rem}.ma6-l{margin:8rem}.ma7-l{margin:16rem}.ml0-l{margin-left:0}.ml1-l{margin-left:.25rem}.ml2-l{margin-left:.5rem}.ml3-l{margin-left:1rem}.ml4-l{margin-left:2rem}.ml5-l{margin-left:4rem}.ml6-l{margin-left:8rem}.ml7-l{margin-left:16rem}.mr0-l{margin-right:0}.mr1-l{margin-right:.25rem}.mr2-l{margin-right:.5rem}.mr3-l{margin-right:1rem}.mr4-l{margin-right:2rem}.mr5-l{margin-right:4rem}.mr6-l{margin-right:8rem}.mr7-l{margin-right:16rem}.mb0-l{margin-bottom:0}.mb1-l{margin-bottom:.25rem}.mb2-l{margin-bottom:.5rem}.mb3-l{margin-bottom:1rem}.mb4-l{margin-bottom:2rem}.mb5-l{margin-bottom:4rem}.mb6-l{margin-bottom:8rem}.mb7-l{margin-bottom:16rem}.mt0-l{margin-top:0}.mt1-l{margin-top:.25rem}.mt2-l{margin-top:.5rem}.mt3-l{margin-top:1rem}.mt4-l{margin-top:2rem}.mt5-l{margin-top:4rem}.mt6-l{margin-top:8rem}.mt7-l{margin-top:16rem}.mv0-l{margin-top:0;margin-bottom:0}.mv1-l{margin-top:.25rem;margin-bottom:.25rem}.mv2-l{margin-top:.5rem;margin-bottom:.5rem}.mv3-l{margin-top:1rem;margin-bottom:1rem}.mv4-l{margin-top:2rem;margin-bottom:2rem}.mv5-l{margin-top:4rem;margin-bottom:4rem}.mv6-l{margin-top:8rem;margin-bottom:8rem}.mv7-l{margin-top:16rem;margin-bottom:16rem}.mh0-l{margin-left:0;margin-right:0}.mh1-l{margin-left:.25rem;margin-right:.25rem}.mh2-l{margin-left:.5rem;margin-right:.5rem}.mh3-l{margin-left:1rem;margin-right:1rem}.mh4-l{margin-left:2rem;margin-right:2rem}.mh5-l{margin-left:4rem;margin-right:4rem}.mh6-l{margin-left:8rem;margin-right:8rem}.mh7-l{margin-left:16rem;margin-right:16rem}}.na1{margin:-.25rem}.na2{margin:-.5rem}.na3{margin:-1rem}.na4{margin:-2rem}.na5{margin:-4rem}.na6{margin:-8rem}.na7{margin:-16rem}.nl1{margin-left:-.25rem}.nl2{margin-left:-.5rem}.nl3{margin-left:-1rem}.nl4{margin-left:-2rem}.nl5{margin-left:-4rem}.nl6{margin-left:-8rem}.nl7{margin-left:-16rem}.nr1{margin-right:-.25rem}.nr2{margin-right:-.5rem}.nr3{margin-right:-1rem}.nr4{margin-right:-2rem}.nr5{margin-right:-4rem}.nr6{margin-right:-8rem}.nr7{margin-right:-16rem}.nb1{margin-bottom:-.25rem}.nb2{margin-bottom:-.5rem}.nb3{margin-bottom:-1rem}.nb4{margin-bottom:-2rem}.nb5{margin-bottom:-4rem}.nb6{margin-bottom:-8rem}.nb7{margin-bottom:-16rem}.nt1{margin-top:-.25rem}.nt2{margin-top:-.5rem}.nt3{margin-top:-1rem}.nt4{margin-top:-2rem}.nt5{margin-top:-4rem}.nt6{margin-top:-8rem}.nt7{margin-top:-16rem}@media screen and (min-width:30em){.na1-ns{margin:-.25rem}.na2-ns{margin:-.5rem}.na3-ns{margin:-1rem}.na4-ns{margin:-2rem}.na5-ns{margin:-4rem}.na6-ns{margin:-8rem}.na7-ns{margin:-16rem}.nl1-ns{margin-left:-.25rem}.nl2-ns{margin-left:-.5rem}.nl3-ns{margin-left:-1rem}.nl4-ns{margin-left:-2rem}.nl5-ns{margin-left:-4rem}.nl6-ns{margin-left:-8rem}.nl7-ns{margin-left:-16rem}.nr1-ns{margin-right:-.25rem}.nr2-ns{margin-right:-.5rem}.nr3-ns{margin-right:-1rem}.nr4-ns{margin-right:-2rem}.nr5-ns{margin-right:-4rem}.nr6-ns{margin-right:-8rem}.nr7-ns{margin-right:-16rem}.nb1-ns{margin-bottom:-.25rem}.nb2-ns{margin-bottom:-.5rem}.nb3-ns{margin-bottom:-1rem}.nb4-ns{margin-bottom:-2rem}.nb5-ns{margin-bottom:-4rem}.nb6-ns{margin-bottom:-8rem}.nb7-ns{margin-bottom:-16rem}.nt1-ns{margin-top:-.25rem}.nt2-ns{margin-top:-.5rem}.nt3-ns{margin-top:-1rem}.nt4-ns{margin-top:-2rem}.nt5-ns{margin-top:-4rem}.nt6-ns{margin-top:-8rem}.nt7-ns{margin-top:-16rem}}@media screen and (min-width:30em) and (max-width:60em){.na1-m{margin:-.25rem}.na2-m{margin:-.5rem}.na3-m{margin:-1rem}.na4-m{margin:-2rem}.na5-m{margin:-4rem}.na6-m{margin:-8rem}.na7-m{margin:-16rem}.nl1-m{margin-left:-.25rem}.nl2-m{margin-left:-.5rem}.nl3-m{margin-left:-1rem}.nl4-m{margin-left:-2rem}.nl5-m{margin-left:-4rem}.nl6-m{margin-left:-8rem}.nl7-m{margin-left:-16rem}.nr1-m{margin-right:-.25rem}.nr2-m{margin-right:-.5rem}.nr3-m{margin-right:-1rem}.nr4-m{margin-right:-2rem}.nr5-m{margin-right:-4rem}.nr6-m{margin-right:-8rem}.nr7-m{margin-right:-16rem}.nb1-m{margin-bottom:-.25rem}.nb2-m{margin-bottom:-.5rem}.nb3-m{margin-bottom:-1rem}.nb4-m{margin-bottom:-2rem}.nb5-m{margin-bottom:-4rem}.nb6-m{margin-bottom:-8rem}.nb7-m{margin-bottom:-16rem}.nt1-m{margin-top:-.25rem}.nt2-m{margin-top:-.5rem}.nt3-m{margin-top:-1rem}.nt4-m{margin-top:-2rem}.nt5-m{margin-top:-4rem}.nt6-m{margin-top:-8rem}.nt7-m{margin-top:-16rem}}@media screen and (min-width:60em){.na1-l{margin:-.25rem}.na2-l{margin:-.5rem}.na3-l{margin:-1rem}.na4-l{margin:-2rem}.na5-l{margin:-4rem}.na6-l{margin:-8rem}.na7-l{margin:-16rem}.nl1-l{margin-left:-.25rem}.nl2-l{margin-left:-.5rem}.nl3-l{margin-left:-1rem}.nl4-l{margin-left:-2rem}.nl5-l{margin-left:-4rem}.nl6-l{margin-left:-8rem}.nl7-l{margin-left:-16rem}.nr1-l{margin-right:-.25rem}.nr2-l{margin-right:-.5rem}.nr3-l{margin-right:-1rem}.nr4-l{margin-right:-2rem}.nr5-l{margin-right:-4rem}.nr6-l{margin-right:-8rem}.nr7-l{margin-right:-16rem}.nb1-l{margin-bottom:-.25rem}.nb2-l{margin-bottom:-.5rem}.nb3-l{margin-bottom:-1rem}.nb4-l{margin-bottom:-2rem}.nb5-l{margin-bottom:-4rem}.nb6-l{margin-bottom:-8rem}.nb7-l{margin-bottom:-16rem}.nt1-l{margin-top:-.25rem}.nt2-l{margin-top:-.5rem}.nt3-l{margin-top:-1rem}.nt4-l{margin-top:-2rem}.nt5-l{margin-top:-4rem}.nt6-l{margin-top:-8rem}.nt7-l{margin-top:-16rem}}.collapse{border-collapse:collapse;border-spacing:0}.striped--light-silver:nth-child(odd){background-color:#aaa}.striped--moon-gray:nth-child(odd){background-color:#ccc}.striped--light-gray:nth-child(odd){background-color:#eee}.striped--near-white:nth-child(odd){background-color:#f4f4f4}.stripe-light:nth-child(odd){background-color:hsla(0,0%,100%,.1)}.stripe-dark:nth-child(odd){background-color:rgba(0,0,0,.1)}.strike{text-decoration:line-through}.underline{text-decoration:underline}.no-underline{text-decoration:none}@media screen and (min-width:30em){.strike-ns{text-decoration:line-through}.underline-ns{text-decoration:underline}.no-underline-ns{text-decoration:none}}@media screen and (min-width:30em) and (max-width:60em){.strike-m{text-decoration:line-through}.underline-m{text-decoration:underline}.no-underline-m{text-decoration:none}}@media screen and (min-width:60em){.strike-l{text-decoration:line-through}.underline-l{text-decoration:underline}.no-underline-l{text-decoration:none}}.tl{text-align:left}.tr{text-align:right}.tc{text-align:center}.tj{text-align:justify}@media screen and (min-width:30em){.tl-ns{text-align:left}.tr-ns{text-align:right}.tc-ns{text-align:center}.tj-ns{text-align:justify}}@media screen and (min-width:30em) and (max-width:60em){.tl-m{text-align:left}.tr-m{text-align:right}.tc-m{text-align:center}.tj-m{text-align:justify}}@media screen and (min-width:60em){.tl-l{text-align:left}.tr-l{text-align:right}.tc-l{text-align:center}.tj-l{text-align:justify}}.ttc{text-transform:capitalize}.ttl{text-transform:lowercase}.ttu{text-transform:uppercase}.ttn{text-transform:none}@media screen and (min-width:30em){.ttc-ns{text-transform:capitalize}.ttl-ns{text-transform:lowercase}.ttu-ns{text-transform:uppercase}.ttn-ns{text-transform:none}}@media screen and (min-width:30em) and (max-width:60em){.ttc-m{text-transform:capitalize}.ttl-m{text-transform:lowercase}.ttu-m{text-transform:uppercase}.ttn-m{text-transform:none}}@media screen and (min-width:60em){.ttc-l{text-transform:capitalize}.ttl-l{text-transform:lowercase}.ttu-l{text-transform:uppercase}.ttn-l{text-transform:none}}.f-6,.f-headline{font-size:6rem}.f-5,.f-subheadline{font-size:5rem}.f1{font-size:3rem}.f2{font-size:2.25rem}.f3{font-size:1.5rem}.f4{font-size:1.25rem}.f5{font-size:1rem}.f6{font-size:.875rem}.f7{font-size:.75rem}@media screen and (min-width:30em){.f-6-ns,.f-headline-ns{font-size:6rem}.f-5-ns,.f-subheadline-ns{font-size:5rem}.f1-ns{font-size:3rem}.f2-ns{font-size:2.25rem}.f3-ns{font-size:1.5rem}.f4-ns{font-size:1.25rem}.f5-ns{font-size:1rem}.f6-ns{font-size:.875rem}.f7-ns{font-size:.75rem}}@media screen and (min-width:30em) and (max-width:60em){.f-6-m,.f-headline-m{font-size:6rem}.f-5-m,.f-subheadline-m{font-size:5rem}.f1-m{font-size:3rem}.f2-m{font-size:2.25rem}.f3-m{font-size:1.5rem}.f4-m{font-size:1.25rem}.f5-m{font-size:1rem}.f6-m{font-size:.875rem}.f7-m{font-size:.75rem}}@media screen and (min-width:60em){.f-6-l,.f-headline-l{font-size:6rem}.f-5-l,.f-subheadline-l{font-size:5rem}.f1-l{font-size:3rem}.f2-l{font-size:2.25rem}.f3-l{font-size:1.5rem}.f4-l{font-size:1.25rem}.f5-l{font-size:1rem}.f6-l{font-size:.875rem}.f7-l{font-size:.75rem}}.measure{max-width:30em}.measure-wide{max-width:34em}.measure-narrow{max-width:20em}.indent{text-indent:1em;margin-top:0;margin-bottom:0}.small-caps{font-feature-settings:"c2sc";font-variant:small-caps}.truncate{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}@media screen and (min-width:30em){.measure-ns{max-width:30em}.measure-wide-ns{max-width:34em}.measure-narrow-ns{max-width:20em}.indent-ns{text-indent:1em;margin-top:0;margin-bottom:0}.small-caps-ns{font-feature-settings:"c2sc";font-variant:small-caps}.truncate-ns{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}}@media screen and (min-width:30em) and (max-width:60em){.measure-m{max-width:30em}.measure-wide-m{max-width:34em}.measure-narrow-m{max-width:20em}.indent-m{text-indent:1em;margin-top:0;margin-bottom:0}.small-caps-m{font-feature-settings:"c2sc";font-variant:small-caps}.truncate-m{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}}@media screen and (min-width:60em){.measure-l{max-width:30em}.measure-wide-l{max-width:34em}.measure-narrow-l{max-width:20em}.indent-l{text-indent:1em;margin-top:0;margin-bottom:0}.small-caps-l{font-feature-settings:"c2sc";font-variant:small-caps}.truncate-l{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}}.overflow-container{overflow-y:scroll}.center{margin-left:auto}.center,.mr-auto{margin-right:auto}.ml-auto{margin-left:auto}@media screen and (min-width:30em){.center-ns{margin-left:auto}.center-ns,.mr-auto-ns{margin-right:auto}.ml-auto-ns{margin-left:auto}}@media screen and (min-width:30em) and (max-width:60em){.center-m{margin-left:auto}.center-m,.mr-auto-m{margin-right:auto}.ml-auto-m{margin-left:auto}}@media screen and (min-width:60em){.center-l{margin-left:auto}.center-l,.mr-auto-l{margin-right:auto}.ml-auto-l{margin-left:auto}}.clip{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}@media screen and (min-width:30em){.clip-ns{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}}@media screen and (min-width:30em) and (max-width:60em){.clip-m{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}}@media screen and (min-width:60em){.clip-l{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}}.ws-normal{white-space:normal}.nowrap{white-space:nowrap}.pre{white-space:pre}@media screen and (min-width:30em){.ws-normal-ns{white-space:normal}.nowrap-ns{white-space:nowrap}.pre-ns{white-space:pre}}@media screen and (min-width:30em) and (max-width:60em){.ws-normal-m{white-space:normal}.nowrap-m{white-space:nowrap}.pre-m{white-space:pre}}@media screen and (min-width:60em){.ws-normal-l{white-space:normal}.nowrap-l{white-space:nowrap}.pre-l{white-space:pre}}.v-base{vertical-align:baseline}.v-mid{vertical-align:middle}.v-top{vertical-align:top}.v-btm{vertical-align:bottom}@media screen and (min-width:30em){.v-base-ns{vertical-align:baseline}.v-mid-ns{vertical-align:middle}.v-top-ns{vertical-align:top}.v-btm-ns{vertical-align:bottom}}@media screen and (min-width:30em) and (max-width:60em){.v-base-m{vertical-align:baseline}.v-mid-m{vertical-align:middle}.v-top-m{vertical-align:top}.v-btm-m{vertical-align:bottom}}@media screen and (min-width:60em){.v-base-l{vertical-align:baseline}.v-mid-l{vertical-align:middle}.v-top-l{vertical-align:top}.v-btm-l{vertical-align:bottom}}.dim{opacity:1}.dim,.dim:focus,.dim:hover{transition:opacity .15s ease-in}.dim:focus,.dim:hover{opacity:.5}.dim:active{opacity:.8;transition:opacity .15s ease-out}.glow,.glow:focus,.glow:hover{transition:opacity .15s ease-in}.glow:focus,.glow:hover{opacity:1}.hide-child .child{opacity:0;transition:opacity .15s ease-in}.hide-child:active .child,.hide-child:focus .child,.hide-child:hover .child{opacity:1;transition:opacity .15s ease-in}.underline-hover:focus,.underline-hover:hover{text-decoration:underline}.grow{-moz-osx-font-smoothing:grayscale;-webkit-backface-visibility:hidden;backface-visibility:hidden;transform:translateZ(0);transition:transform .25s ease-out}.grow:focus,.grow:hover{transform:scale(1.05)}.grow:active{transform:scale(.9)}.grow-large{-moz-osx-font-smoothing:grayscale;-webkit-backface-visibility:hidden;backface-visibility:hidden;transform:translateZ(0);transition:transform .25s ease-in-out}.grow-large:focus,.grow-large:hover{transform:scale(1.2)}.grow-large:active{transform:scale(.95)}.pointer:hover,.shadow-hover{cursor:pointer}.shadow-hover{position:relative;transition:all .5s cubic-bezier(.165,.84,.44,1)}.shadow-hover:after{content:"";box-shadow:0 0 16px 2px rgba(0,0,0,.2);border-radius:inherit;opacity:0;position:absolute;top:0;left:0;width:100%;height:100%;z-index:-1;transition:opacity .5s cubic-bezier(.165,.84,.44,1)}.shadow-hover:focus:after,.shadow-hover:hover:after{opacity:1}.bg-animate,.bg-animate:focus,.bg-animate:hover{transition:background-color .15s ease-in-out}.z-0{z-index:0}.z-1{z-index:1}.z-2{z-index:2}.z-3{z-index:3}.z-4{z-index:4}.z-5{z-index:5}.z-999{z-index:999}.z-9999{z-index:9999}.z-max{z-index:2147483647}.z-inherit{z-index:inherit}.z-initial{z-index:auto}.z-unset{z-index:unset}.nested-copy-line-height ol,.nested-copy-line-height p,.nested-copy-line-height ul{line-height:1.5}.nested-headline-line-height h1,.nested-headline-line-height h2,.nested-headline-line-height h3,.nested-headline-line-height h4,.nested-headline-line-height h5,.nested-headline-line-height h6{line-height:1.25}.nested-list-reset ol,.nested-list-reset ul{padding-left:0;margin-left:0;list-style-type:none}.nested-copy-indent p+p{text-indent:1em;margin-top:0;margin-bottom:0}.nested-copy-separator p+p{margin-top:1.5em}.nested-img img{width:100%;max-width:100%;display:block}.nested-links a{color:#357edd;transition:color .15s ease-in}.nested-links a:focus,.nested-links a:hover{color:#96ccff;transition:color .15s ease-in}.pre,pre{overflow-x:auto;overflow-y:hidden;overflow:scroll}pre code{display:block;padding:1.5em;font-size:.875rem;line-height:2}pre,pre code{white-space:pre}pre{background-color:#222;color:#ddd;-webkit-hyphens:none;-ms-hyphens:none;hyphens:none;position:relative}.pagination{margin:3rem 0}.pagination li{display:inline-block;margin-right:.375rem;font-size:.875rem;margin-bottom:2.5em}.pagination li a{padding:.5rem .625rem;background-color:#fff;color:#333;border:1px solid #ddd;border-radius:3px;text-decoration:none}.pagination li.disabled{display:none}.pagination li.active a:active,.pagination li.active a:link,.pagination li.active a:visited{background-color:#ddd}.facebook,.github,.gitlab,.instagram,.keybase,.linkedin,.mastodon,.medium,.slack,.stackoverflow,.twitter,.youtube{fill:#bababa}.new-window{opacity:0;display:inline-block;vertical-align:top}.link-transition:hover .new-window{opacity:1}.facebook:hover{fill:#3b5998}.twitter:hover{fill:#1da1f2}.instagram:hover{fill:#e1306c}.youtube:hover{fill:#cd201f}.github:hover{fill:#6cc644}.gitlab:hover{fill:#fc6d26}.keybase:hover{fill:#3d76ff}.linkedin:hover,.medium:hover{fill:#0077b5}.mastodon:hover{fill:#3088d4}.slack:hover{fill:#e01e5a}.stackoverflow:hover{fill:#f48024}#TableOfContents ul li{margin-bottom:1em}.lh-copy blockquote{display:block;font-size:.875em;margin-left:2rem;margin-top:2rem;margin-bottom:2rem;border-left:4px solid #ccc;padding-left:1rem} \ No newline at end of file diff --git a/public/dist/css/app.4fc0b62e4b82c997bb0041217cd6b979.css b/public/dist/css/app.4fc0b62e4b82c997bb0041217cd6b979.css new file mode 100644 index 00000000..de2428dc --- /dev/null +++ b/public/dist/css/app.4fc0b62e4b82c997bb0041217cd6b979.css @@ -0,0 +1,5876 @@ +/*! TACHYONS v4.9.1 | http://tachyons.io */ + +/* + * + * ________ ______ + * ___ __/_____ _________ /______ ______________________ + * __ / _ __ `/ ___/_ __ \_ / / / __ \_ __ \_ ___/ + * _ / / /_/ // /__ _ / / / /_/ // /_/ / / / /(__ ) + * /_/ \__,_/ \___/ /_/ /_/_\__, / \____//_/ /_//____/ + * /____/ + * + * TABLE OF CONTENTS + * + * 1. External Library Includes + * - Normalize.css | http://normalize.css.github.io + * 2. Tachyons Modules + * 3. Variables + * - Media Queries + * - Colors + * 4. Debugging + * - Debug all + * - Debug children + * + */ + +/* External Library Includes */ + +/*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */ + +/* Document + ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in iOS. + */ + +html { + line-height: 1.15; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/* Sections + ========================================================================== */ + +/** + * Remove the margin in all browsers. + */ + +body { + margin: 0; +} + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/* Grouping content + ========================================================================== */ + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + +hr { + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +pre { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Remove the gray background on active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * 1. Remove the bottom border in Chrome 57- + * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. + */ + +abbr[title] { + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + text-decoration: underline dotted; /* 2 */ +} + +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + +b, +strong { + font-weight: bolder; +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +code, +kbd, +samp { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/** + * Add the correct font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` elements from affecting the line height in + * all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove the border on images inside links in IE 10. + */ + +img { + border-style: none; +} + +/* Forms + ========================================================================== */ + +/** + * 1. Change the font styles in all browsers. + * 2. Remove the margin in Firefox and Safari. + */ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ +} + +/** + * Show the overflow in IE. + * 1. Show the overflow in Edge. + */ + +button, +input { /* 1 */ + overflow: visible; +} + +/** + * Remove the inheritance of text transform in Edge, Firefox, and IE. + * 1. Remove the inheritance of text transform in Firefox. + */ + +button, +select { /* 1 */ + text-transform: none; +} + +/** + * Correct the inability to style clickable types in iOS and Safari. + */ + +button, +[type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} + +/** + * Remove the inner border and padding in Firefox. + */ + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus styles unset by the previous rule. + */ + +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; +} + +/** + * Correct the padding in Firefox. + */ + +fieldset { + padding: 0.35em 0.75em 0.625em; +} + +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + +legend { + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ +} + +/** + * Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + +progress { + vertical-align: baseline; +} + +/** + * Remove the default vertical scrollbar in IE 10+. + */ + +textarea { + overflow: auto; +} + +/** + * 1. Add the correct box sizing in IE 10. + * 2. Remove the padding in IE 10. + */ + +[type="checkbox"], +[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type="search"] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Remove the inner padding in Chrome and Safari on macOS. + */ + +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + +::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} + +/* Interactive + ========================================================================== */ + +/* + * Add the correct display in Edge, IE 10+, and Firefox. + */ + +details { + display: block; +} + +/* + * Add the correct display in all browsers. + */ + +summary { + display: list-item; +} + +/* Misc + ========================================================================== */ + +/** + * Add the correct display in IE 10+. + */ + +template { + display: none; +} + +/** + * Add the correct display in IE 10. + */ + +[hidden] { + display: none; +} + +/* Modules */ + +/* + + BOX SIZING + +*/ + +html, +body, +div, +article, +aside, +section, +main, +nav, +footer, +header, +form, +fieldset, +legend, +pre, +code, +a, +h1,h2,h3,h4,h5,h6, +p, +ul, +ol, +li, +dl, +dt, +dd, +blockquote, +figcaption, +figure, +textarea, +table, +td, +th, +tr, +input[type="email"], +input[type="number"], +input[type="password"], +input[type="tel"], +input[type="text"], +input[type="url"], +.border-box { + box-sizing: border-box; +} + +/* + + ASPECT RATIOS + +*/ + +/* This is for fluid media that is embedded from third party sites like youtube, vimeo etc. + * Wrap the outer element in aspect-ratio and then extend it with the desired ratio i.e + * Make sure there are no height and width attributes on the embedded media. + * Adapted from: https://github.com/suitcss/components-flex-embed + * + * Example: + * + *
+ * + *
+ * + * */ + +.aspect-ratio { + height: 0; + position: relative; +} + +.aspect-ratio--16x9 { padding-bottom: 56.25%; } + +.aspect-ratio--9x16 { padding-bottom: 177.77%; } + +.aspect-ratio--4x3 { padding-bottom: 75%; } + +.aspect-ratio--3x4 { padding-bottom: 133.33%; } + +.aspect-ratio--6x4 { padding-bottom: 66.6%; } + +.aspect-ratio--4x6 { padding-bottom: 150%; } + +.aspect-ratio--8x5 { padding-bottom: 62.5%; } + +.aspect-ratio--5x8 { padding-bottom: 160%; } + +.aspect-ratio--7x5 { padding-bottom: 71.42%; } + +.aspect-ratio--5x7 { padding-bottom: 140%; } + +.aspect-ratio--1x1 { padding-bottom: 100%; } + +.aspect-ratio--object { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100; +} + +@media screen and (min-width: 30em){ + .aspect-ratio-ns { + height: 0; + position: relative; + } + .aspect-ratio--16x9-ns { padding-bottom: 56.25%; } + .aspect-ratio--9x16-ns { padding-bottom: 177.77%; } + .aspect-ratio--4x3-ns { padding-bottom: 75%; } + .aspect-ratio--3x4-ns { padding-bottom: 133.33%; } + .aspect-ratio--6x4-ns { padding-bottom: 66.6%; } + .aspect-ratio--4x6-ns { padding-bottom: 150%; } + .aspect-ratio--8x5-ns { padding-bottom: 62.5%; } + .aspect-ratio--5x8-ns { padding-bottom: 160%; } + .aspect-ratio--7x5-ns { padding-bottom: 71.42%; } + .aspect-ratio--5x7-ns { padding-bottom: 140%; } + .aspect-ratio--1x1-ns { padding-bottom: 100%; } + .aspect-ratio--object-ns { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100; + } +} + +@media screen and (min-width: 30em) and (max-width: 60em){ + .aspect-ratio-m { + height: 0; + position: relative; + } + .aspect-ratio--16x9-m { padding-bottom: 56.25%; } + .aspect-ratio--9x16-m { padding-bottom: 177.77%; } + .aspect-ratio--4x3-m { padding-bottom: 75%; } + .aspect-ratio--3x4-m { padding-bottom: 133.33%; } + .aspect-ratio--6x4-m { padding-bottom: 66.6%; } + .aspect-ratio--4x6-m { padding-bottom: 150%; } + .aspect-ratio--8x5-m { padding-bottom: 62.5%; } + .aspect-ratio--5x8-m { padding-bottom: 160%; } + .aspect-ratio--7x5-m { padding-bottom: 71.42%; } + .aspect-ratio--5x7-m { padding-bottom: 140%; } + .aspect-ratio--1x1-m { padding-bottom: 100%; } + .aspect-ratio--object-m { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100; + } +} + +@media screen and (min-width: 60em){ + .aspect-ratio-l { + height: 0; + position: relative; + } + .aspect-ratio--16x9-l { padding-bottom: 56.25%; } + .aspect-ratio--9x16-l { padding-bottom: 177.77%; } + .aspect-ratio--4x3-l { padding-bottom: 75%; } + .aspect-ratio--3x4-l { padding-bottom: 133.33%; } + .aspect-ratio--6x4-l { padding-bottom: 66.6%; } + .aspect-ratio--4x6-l { padding-bottom: 150%; } + .aspect-ratio--8x5-l { padding-bottom: 62.5%; } + .aspect-ratio--5x8-l { padding-bottom: 160%; } + .aspect-ratio--7x5-l { padding-bottom: 71.42%; } + .aspect-ratio--5x7-l { padding-bottom: 140%; } + .aspect-ratio--1x1-l { padding-bottom: 100%; } + .aspect-ratio--object-l { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100; + } +} + +/* + + IMAGES + Docs: http://tachyons.io/docs/elements/images/ + +*/ + +/* Responsive images! */ + +img { max-width: 100%; } + +/* + + BACKGROUND SIZE + Docs: http://tachyons.io/docs/themes/background-size/ + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +/* + Often used in combination with background image set as an inline style + on an html element. +*/ + +.cover { background-size: cover!important; } + +.contain { background-size: contain!important; } + +@media screen and (min-width: 30em) { + .cover-ns { background-size: cover!important; } + .contain-ns { background-size: contain!important; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .cover-m { background-size: cover!important; } + .contain-m { background-size: contain!important; } +} + +@media screen and (min-width: 60em) { + .cover-l { background-size: cover!important; } + .contain-l { background-size: contain!important; } +} + +/* + + BACKGROUND POSITION + + Base: + bg = background + + Modifiers: + -center = center center + -top = top center + -right = center right + -bottom = bottom center + -left = center left + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + + */ + +.bg-center { + background-repeat: no-repeat; + background-position: center center; +} + +.bg-top { + background-repeat: no-repeat; + background-position: top center; +} + +.bg-right { + background-repeat: no-repeat; + background-position: center right; +} + +.bg-bottom { + background-repeat: no-repeat; + background-position: bottom center; +} + +.bg-left { + background-repeat: no-repeat; + background-position: center left; +} + +@media screen and (min-width: 30em) { + .bg-center-ns { + background-repeat: no-repeat; + background-position: center center; + } + + .bg-top-ns { + background-repeat: no-repeat; + background-position: top center; + } + + .bg-right-ns { + background-repeat: no-repeat; + background-position: center right; + } + + .bg-bottom-ns { + background-repeat: no-repeat; + background-position: bottom center; + } + + .bg-left-ns { + background-repeat: no-repeat; + background-position: center left; + } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .bg-center-m { + background-repeat: no-repeat; + background-position: center center; + } + + .bg-top-m { + background-repeat: no-repeat; + background-position: top center; + } + + .bg-right-m { + background-repeat: no-repeat; + background-position: center right; + } + + .bg-bottom-m { + background-repeat: no-repeat; + background-position: bottom center; + } + + .bg-left-m { + background-repeat: no-repeat; + background-position: center left; + } +} + +@media screen and (min-width: 60em) { + .bg-center-l { + background-repeat: no-repeat; + background-position: center center; + } + + .bg-top-l { + background-repeat: no-repeat; + background-position: top center; + } + + .bg-right-l { + background-repeat: no-repeat; + background-position: center right; + } + + .bg-bottom-l { + background-repeat: no-repeat; + background-position: bottom center; + } + + .bg-left-l { + background-repeat: no-repeat; + background-position: center left; + } +} + +/* + + OUTLINES + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.outline { outline: 1px solid; } + +.outline-transparent { outline: 1px solid transparent; } + +.outline-0 { outline: 0; } + +@media screen and (min-width: 30em) { + .outline-ns { outline: 1px solid; } + .outline-transparent-ns { outline: 1px solid transparent; } + .outline-0-ns { outline: 0; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .outline-m { outline: 1px solid; } + .outline-transparent-m { outline: 1px solid transparent; } + .outline-0-m { outline: 0; } +} + +@media screen and (min-width: 60em) { + .outline-l { outline: 1px solid; } + .outline-transparent-l { outline: 1px solid transparent; } + .outline-0-l { outline: 0; } +} + +/* + + BORDERS + Docs: http://tachyons.io/docs/themes/borders/ + + Base: + b = border + + Modifiers: + a = all + t = top + r = right + b = bottom + l = left + n = none + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.ba { border-style: solid; border-width: 1px; } + +.bt { border-top-style: solid; border-top-width: 1px; } + +.br { border-right-style: solid; border-right-width: 1px; } + +.bb { border-bottom-style: solid; border-bottom-width: 1px; } + +.bl { border-left-style: solid; border-left-width: 1px; } + +.bn { border-style: none; border-width: 0; } + +@media screen and (min-width: 30em) { + .ba-ns { border-style: solid; border-width: 1px; } + .bt-ns { border-top-style: solid; border-top-width: 1px; } + .br-ns { border-right-style: solid; border-right-width: 1px; } + .bb-ns { border-bottom-style: solid; border-bottom-width: 1px; } + .bl-ns { border-left-style: solid; border-left-width: 1px; } + .bn-ns { border-style: none; border-width: 0; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .ba-m { border-style: solid; border-width: 1px; } + .bt-m { border-top-style: solid; border-top-width: 1px; } + .br-m { border-right-style: solid; border-right-width: 1px; } + .bb-m { border-bottom-style: solid; border-bottom-width: 1px; } + .bl-m { border-left-style: solid; border-left-width: 1px; } + .bn-m { border-style: none; border-width: 0; } +} + +@media screen and (min-width: 60em) { + .ba-l { border-style: solid; border-width: 1px; } + .bt-l { border-top-style: solid; border-top-width: 1px; } + .br-l { border-right-style: solid; border-right-width: 1px; } + .bb-l { border-bottom-style: solid; border-bottom-width: 1px; } + .bl-l { border-left-style: solid; border-left-width: 1px; } + .bn-l { border-style: none; border-width: 0; } +} + +/* + + BORDER COLORS + Docs: http://tachyons.io/docs/themes/borders/ + + Border colors can be used to extend the base + border classes ba,bt,bb,br,bl found in the _borders.css file. + + The base border class by default will set the color of the border + to that of the current text color. These classes are for the cases + where you desire for the text and border colors to be different. + + Base: + b = border + + Modifiers: + --color-name = each color variable name is also a border color name + +*/ + +.b--black { border-color: #000; } + +.b--near-black { border-color: #111; } + +.b--dark-gray { border-color: #333; } + +.b--mid-gray { border-color: #555; } + +.b--gray { border-color: #777; } + +.b--silver { border-color: #999; } + +.b--light-silver { border-color: #aaa; } + +.b--moon-gray { border-color: #ccc; } + +.b--light-gray { border-color: #eee; } + +.b--near-white { border-color: #f4f4f4; } + +.b--white { border-color: #fff; } + +.b--white-90 { border-color: rgba(255, 255, 255, .9); } + +.b--white-80 { border-color: rgba(255, 255, 255, .8); } + +.b--white-70 { border-color: rgba(255, 255, 255, .7); } + +.b--white-60 { border-color: rgba(255, 255, 255, .6); } + +.b--white-50 { border-color: rgba(255, 255, 255, .5); } + +.b--white-40 { border-color: rgba(255, 255, 255, .4); } + +.b--white-30 { border-color: rgba(255, 255, 255, .3); } + +.b--white-20 { border-color: rgba(255, 255, 255, .2); } + +.b--white-10 { border-color: rgba(255, 255, 255, .1); } + +.b--white-05 { border-color: rgba(255, 255, 255, .05); } + +.b--white-025 { border-color: rgba(255, 255, 255, .025); } + +.b--white-0125 { border-color: rgba(255, 255, 255, .0125); } + +.b--black-90 { border-color: rgba(0, 0, 0, .9); } + +.b--black-80 { border-color: rgba(0, 0, 0, .8); } + +.b--black-70 { border-color: rgba(0, 0, 0, .7); } + +.b--black-60 { border-color: rgba(0, 0, 0, .6); } + +.b--black-50 { border-color: rgba(0, 0, 0, .5); } + +.b--black-40 { border-color: rgba(0, 0, 0, .4); } + +.b--black-30 { border-color: rgba(0, 0, 0, .3); } + +.b--black-20 { border-color: rgba(0, 0, 0, .2); } + +.b--black-10 { border-color: rgba(0, 0, 0, .1); } + +.b--black-05 { border-color: rgba(0, 0, 0, .05); } + +.b--black-025 { border-color: rgba(0, 0, 0, .025); } + +.b--black-0125 { border-color: rgba(0, 0, 0, .0125); } + +.b--dark-red { border-color: #e7040f; } + +.b--red { border-color: #ff4136; } + +.b--light-red { border-color: #ff725c; } + +.b--orange { border-color: #ff6300; } + +.b--gold { border-color: #ffb700; } + +.b--yellow { border-color: #ffd700; } + +.b--light-yellow { border-color: #fbf1a9; } + +.b--purple { border-color: #5e2ca5; } + +.b--light-purple { border-color: #a463f2; } + +.b--dark-pink { border-color: #d5008f; } + +.b--hot-pink { border-color: #ff41b4; } + +.b--pink { border-color: #ff80cc; } + +.b--light-pink { border-color: #ffa3d7; } + +.b--dark-green { border-color: #137752; } + +.b--green { border-color: #19a974; } + +.b--light-green { border-color: #9eebcf; } + +.b--navy { border-color: #001b44; } + +.b--dark-blue { border-color: #00449e; } + +.b--blue { border-color: #357edd; } + +.b--light-blue { border-color: #96ccff; } + +.b--lightest-blue { border-color: #cdecff; } + +.b--washed-blue { border-color: #f6fffe; } + +.b--washed-green { border-color: #e8fdf5; } + +.b--washed-yellow { border-color: #fffceb; } + +.b--washed-red { border-color: #ffdfdf; } + +.b--transparent { border-color: transparent; } + +.b--inherit { border-color: inherit; } + +/* + + BORDER RADIUS + Docs: http://tachyons.io/docs/themes/border-radius/ + + Base: + br = border-radius + + Modifiers: + 0 = 0/none + 1 = 1st step in scale + 2 = 2nd step in scale + 3 = 3rd step in scale + 4 = 4th step in scale + + Literal values: + -100 = 100% + -pill = 9999px + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.br0 { border-radius: 0; } + +.br1 { border-radius: .125rem; } + +.br2 { border-radius: .25rem; } + +.br3 { border-radius: .5rem; } + +.br4 { border-radius: 1rem; } + +.br-100 { border-radius: 100%; } + +.br-pill { border-radius: 9999px; } + +.br--bottom { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + +.br--top { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + +.br--right { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + +.br--left { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + +@media screen and (min-width: 30em) { + .br0-ns { border-radius: 0; } + .br1-ns { border-radius: .125rem; } + .br2-ns { border-radius: .25rem; } + .br3-ns { border-radius: .5rem; } + .br4-ns { border-radius: 1rem; } + .br-100-ns { border-radius: 100%; } + .br-pill-ns { border-radius: 9999px; } + .br--bottom-ns { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + .br--top-ns { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + .br--right-ns { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .br--left-ns { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .br0-m { border-radius: 0; } + .br1-m { border-radius: .125rem; } + .br2-m { border-radius: .25rem; } + .br3-m { border-radius: .5rem; } + .br4-m { border-radius: 1rem; } + .br-100-m { border-radius: 100%; } + .br-pill-m { border-radius: 9999px; } + .br--bottom-m { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + .br--top-m { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + .br--right-m { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .br--left-m { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } +} + +@media screen and (min-width: 60em) { + .br0-l { border-radius: 0; } + .br1-l { border-radius: .125rem; } + .br2-l { border-radius: .25rem; } + .br3-l { border-radius: .5rem; } + .br4-l { border-radius: 1rem; } + .br-100-l { border-radius: 100%; } + .br-pill-l { border-radius: 9999px; } + .br--bottom-l { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + .br--top-l { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + .br--right-l { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .br--left-l { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } +} + +/* + + BORDER STYLES + Docs: http://tachyons.io/docs/themes/borders/ + + Depends on base border module in _borders.css + + Base: + b = border-style + + Modifiers: + --none = none + --dotted = dotted + --dashed = dashed + --solid = solid + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + + */ + +.b--dotted { border-style: dotted; } + +.b--dashed { border-style: dashed; } + +.b--solid { border-style: solid; } + +.b--none { border-style: none; } + +@media screen and (min-width: 30em) { + .b--dotted-ns { border-style: dotted; } + .b--dashed-ns { border-style: dashed; } + .b--solid-ns { border-style: solid; } + .b--none-ns { border-style: none; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .b--dotted-m { border-style: dotted; } + .b--dashed-m { border-style: dashed; } + .b--solid-m { border-style: solid; } + .b--none-m { border-style: none; } +} + +@media screen and (min-width: 60em) { + .b--dotted-l { border-style: dotted; } + .b--dashed-l { border-style: dashed; } + .b--solid-l { border-style: solid; } + .b--none-l { border-style: none; } +} + +/* + + BORDER WIDTHS + Docs: http://tachyons.io/docs/themes/borders/ + + Base: + bw = border-width + + Modifiers: + 0 = 0 width border + 1 = 1st step in border-width scale + 2 = 2nd step in border-width scale + 3 = 3rd step in border-width scale + 4 = 4th step in border-width scale + 5 = 5th step in border-width scale + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.bw0 { border-width: 0; } + +.bw1 { border-width: .125rem; } + +.bw2 { border-width: .25rem; } + +.bw3 { border-width: .5rem; } + +.bw4 { border-width: 1rem; } + +.bw5 { border-width: 2rem; } + +/* Resets */ + +.bt-0 { border-top-width: 0; } + +.br-0 { border-right-width: 0; } + +.bb-0 { border-bottom-width: 0; } + +.bl-0 { border-left-width: 0; } + +@media screen and (min-width: 30em) { + .bw0-ns { border-width: 0; } + .bw1-ns { border-width: .125rem; } + .bw2-ns { border-width: .25rem; } + .bw3-ns { border-width: .5rem; } + .bw4-ns { border-width: 1rem; } + .bw5-ns { border-width: 2rem; } + .bt-0-ns { border-top-width: 0; } + .br-0-ns { border-right-width: 0; } + .bb-0-ns { border-bottom-width: 0; } + .bl-0-ns { border-left-width: 0; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .bw0-m { border-width: 0; } + .bw1-m { border-width: .125rem; } + .bw2-m { border-width: .25rem; } + .bw3-m { border-width: .5rem; } + .bw4-m { border-width: 1rem; } + .bw5-m { border-width: 2rem; } + .bt-0-m { border-top-width: 0; } + .br-0-m { border-right-width: 0; } + .bb-0-m { border-bottom-width: 0; } + .bl-0-m { border-left-width: 0; } +} + +@media screen and (min-width: 60em) { + .bw0-l { border-width: 0; } + .bw1-l { border-width: .125rem; } + .bw2-l { border-width: .25rem; } + .bw3-l { border-width: .5rem; } + .bw4-l { border-width: 1rem; } + .bw5-l { border-width: 2rem; } + .bt-0-l { border-top-width: 0; } + .br-0-l { border-right-width: 0; } + .bb-0-l { border-bottom-width: 0; } + .bl-0-l { border-left-width: 0; } +} + +/* + + BOX-SHADOW + Docs: http://tachyons.io/docs/themes/box-shadow/ + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + + */ + +.shadow-1 { box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, .2); } + +.shadow-2 { box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, .2); } + +.shadow-3 { box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, .2); } + +.shadow-4 { box-shadow: 2px 2px 8px 0px rgba(0, 0, 0, .2); } + +.shadow-5 { box-shadow: 4px 4px 8px 0px rgba(0, 0, 0, .2); } + +@media screen and (min-width: 30em) { + .shadow-1-ns { box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, .2); } + .shadow-2-ns { box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, .2); } + .shadow-3-ns { box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, .2); } + .shadow-4-ns { box-shadow: 2px 2px 8px 0px rgba(0, 0, 0, .2); } + .shadow-5-ns { box-shadow: 4px 4px 8px 0px rgba(0, 0, 0, .2); } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .shadow-1-m { box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, .2); } + .shadow-2-m { box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, .2); } + .shadow-3-m { box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, .2); } + .shadow-4-m { box-shadow: 2px 2px 8px 0px rgba(0, 0, 0, .2); } + .shadow-5-m { box-shadow: 4px 4px 8px 0px rgba(0, 0, 0, .2); } +} + +@media screen and (min-width: 60em) { + .shadow-1-l { box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, .2); } + .shadow-2-l { box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, .2); } + .shadow-3-l { box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, .2); } + .shadow-4-l { box-shadow: 2px 2px 8px 0px rgba(0, 0, 0, .2); } + .shadow-5-l { box-shadow: 4px 4px 8px 0px rgba(0, 0, 0, .2); } +} + +/* + + CODE + +*/ + +.pre { + overflow-x: auto; + overflow-y: hidden; + overflow: scroll; +} + +/* + + COORDINATES + Docs: http://tachyons.io/docs/layout/position/ + + Use in combination with the position module. + + Base: + top + bottom + right + left + + Modifiers: + -0 = literal value 0 + -1 = literal value 1 + -2 = literal value 2 + --1 = literal value -1 + --2 = literal value -2 + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.top-0 { top: 0; } + +.right-0 { right: 0; } + +.bottom-0 { bottom: 0; } + +.left-0 { left: 0; } + +.top-1 { top: 1rem; } + +.right-1 { right: 1rem; } + +.bottom-1 { bottom: 1rem; } + +.left-1 { left: 1rem; } + +.top-2 { top: 2rem; } + +.right-2 { right: 2rem; } + +.bottom-2 { bottom: 2rem; } + +.left-2 { left: 2rem; } + +.top--1 { top: -1rem; } + +.right--1 { right: -1rem; } + +.bottom--1 { bottom: -1rem; } + +.left--1 { left: -1rem; } + +.top--2 { top: -2rem; } + +.right--2 { right: -2rem; } + +.bottom--2 { bottom: -2rem; } + +.left--2 { left: -2rem; } + +.absolute--fill { + top: 0; + right: 0; + bottom: 0; + left: 0; +} + +@media screen and (min-width: 30em) { + .top-0-ns { top: 0; } + .left-0-ns { left: 0; } + .right-0-ns { right: 0; } + .bottom-0-ns { bottom: 0; } + .top-1-ns { top: 1rem; } + .left-1-ns { left: 1rem; } + .right-1-ns { right: 1rem; } + .bottom-1-ns { bottom: 1rem; } + .top-2-ns { top: 2rem; } + .left-2-ns { left: 2rem; } + .right-2-ns { right: 2rem; } + .bottom-2-ns { bottom: 2rem; } + .top--1-ns { top: -1rem; } + .right--1-ns { right: -1rem; } + .bottom--1-ns { bottom: -1rem; } + .left--1-ns { left: -1rem; } + .top--2-ns { top: -2rem; } + .right--2-ns { right: -2rem; } + .bottom--2-ns { bottom: -2rem; } + .left--2-ns { left: -2rem; } + .absolute--fill-ns { + top: 0; + right: 0; + bottom: 0; + left: 0; + } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .top-0-m { top: 0; } + .left-0-m { left: 0; } + .right-0-m { right: 0; } + .bottom-0-m { bottom: 0; } + .top-1-m { top: 1rem; } + .left-1-m { left: 1rem; } + .right-1-m { right: 1rem; } + .bottom-1-m { bottom: 1rem; } + .top-2-m { top: 2rem; } + .left-2-m { left: 2rem; } + .right-2-m { right: 2rem; } + .bottom-2-m { bottom: 2rem; } + .top--1-m { top: -1rem; } + .right--1-m { right: -1rem; } + .bottom--1-m { bottom: -1rem; } + .left--1-m { left: -1rem; } + .top--2-m { top: -2rem; } + .right--2-m { right: -2rem; } + .bottom--2-m { bottom: -2rem; } + .left--2-m { left: -2rem; } + .absolute--fill-m { + top: 0; + right: 0; + bottom: 0; + left: 0; + } +} + +@media screen and (min-width: 60em) { + .top-0-l { top: 0; } + .left-0-l { left: 0; } + .right-0-l { right: 0; } + .bottom-0-l { bottom: 0; } + .top-1-l { top: 1rem; } + .left-1-l { left: 1rem; } + .right-1-l { right: 1rem; } + .bottom-1-l { bottom: 1rem; } + .top-2-l { top: 2rem; } + .left-2-l { left: 2rem; } + .right-2-l { right: 2rem; } + .bottom-2-l { bottom: 2rem; } + .top--1-l { top: -1rem; } + .right--1-l { right: -1rem; } + .bottom--1-l { bottom: -1rem; } + .left--1-l { left: -1rem; } + .top--2-l { top: -2rem; } + .right--2-l { right: -2rem; } + .bottom--2-l { bottom: -2rem; } + .left--2-l { left: -2rem; } + .absolute--fill-l { + top: 0; + right: 0; + bottom: 0; + left: 0; + } +} + +/* + + CLEARFIX + http://tachyons.io/docs/layout/clearfix/ + +*/ + +/* Nicolas Gallaghers Clearfix solution + Ref: http://nicolasgallagher.com/micro-clearfix-hack/ */ + +.cf:before, +.cf:after { content: " "; display: table; } + +.cf:after { clear: both; } + +.cf { *zoom: 1; } + +.cl { clear: left; } + +.cr { clear: right; } + +.cb { clear: both; } + +.cn { clear: none; } + +@media screen and (min-width: 30em) { + .cl-ns { clear: left; } + .cr-ns { clear: right; } + .cb-ns { clear: both; } + .cn-ns { clear: none; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .cl-m { clear: left; } + .cr-m { clear: right; } + .cb-m { clear: both; } + .cn-m { clear: none; } +} + +@media screen and (min-width: 60em) { + .cl-l { clear: left; } + .cr-l { clear: right; } + .cb-l { clear: both; } + .cn-l { clear: none; } +} + +/* + + DISPLAY + Docs: http://tachyons.io/docs/layout/display + + Base: + d = display + + Modifiers: + n = none + b = block + ib = inline-block + it = inline-table + t = table + tc = table-cell + t-row = table-row + t-columm = table-column + t-column-group = table-column-group + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.dn { display: none; } + +.di { display: inline; } + +.db { display: block; } + +.dib { display: inline-block; } + +.dit { display: inline-table; } + +.dt { display: table; } + +.dtc { display: table-cell; } + +.dt-row { display: table-row; } + +.dt-row-group { display: table-row-group; } + +.dt-column { display: table-column; } + +.dt-column-group { display: table-column-group; } + +/* + This will set table to full width and then + all cells will be equal width +*/ + +.dt--fixed { + table-layout: fixed; + width: 100%; +} + +@media screen and (min-width: 30em) { + .dn-ns { display: none; } + .di-ns { display: inline; } + .db-ns { display: block; } + .dib-ns { display: inline-block; } + .dit-ns { display: inline-table; } + .dt-ns { display: table; } + .dtc-ns { display: table-cell; } + .dt-row-ns { display: table-row; } + .dt-row-group-ns { display: table-row-group; } + .dt-column-ns { display: table-column; } + .dt-column-group-ns { display: table-column-group; } + + .dt--fixed-ns { + table-layout: fixed; + width: 100%; + } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .dn-m { display: none; } + .di-m { display: inline; } + .db-m { display: block; } + .dib-m { display: inline-block; } + .dit-m { display: inline-table; } + .dt-m { display: table; } + .dtc-m { display: table-cell; } + .dt-row-m { display: table-row; } + .dt-row-group-m { display: table-row-group; } + .dt-column-m { display: table-column; } + .dt-column-group-m { display: table-column-group; } + + .dt--fixed-m { + table-layout: fixed; + width: 100%; + } +} + +@media screen and (min-width: 60em) { + .dn-l { display: none; } + .di-l { display: inline; } + .db-l { display: block; } + .dib-l { display: inline-block; } + .dit-l { display: inline-table; } + .dt-l { display: table; } + .dtc-l { display: table-cell; } + .dt-row-l { display: table-row; } + .dt-row-group-l { display: table-row-group; } + .dt-column-l { display: table-column; } + .dt-column-group-l { display: table-column-group; } + + .dt--fixed-l { + table-layout: fixed; + width: 100%; + } +} + +/* + + FLEXBOX + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.flex { display: -webkit-box; display: -ms-flexbox; display: flex; } + +.inline-flex { display: -webkit-inline-box; display: -ms-inline-flexbox; display: inline-flex; } + +/* 1. Fix for Chrome 44 bug. + * https://code.google.com/p/chromium/issues/detail?id=506893 */ + +.flex-auto { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + min-width: 0; /* 1 */ + min-height: 0; /* 1 */ +} + +.flex-none { -webkit-box-flex: 0; -ms-flex: none; flex: none; } + +.flex-column { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } + +.flex-row { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; } + +.flex-wrap { -ms-flex-wrap: wrap; flex-wrap: wrap; } + +.flex-nowrap { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } + +.flex-wrap-reverse { -ms-flex-wrap: wrap-reverse; flex-wrap: wrap-reverse; } + +.flex-column-reverse { -webkit-box-orient: vertical; -webkit-box-direction: reverse; -ms-flex-direction: column-reverse; flex-direction: column-reverse; } + +.flex-row-reverse { -webkit-box-orient: horizontal; -webkit-box-direction: reverse; -ms-flex-direction: row-reverse; flex-direction: row-reverse; } + +.items-start { -webkit-box-align: start; -ms-flex-align: start; align-items: flex-start; } + +.items-end { -webkit-box-align: end; -ms-flex-align: end; align-items: flex-end; } + +.items-center { -webkit-box-align: center; -ms-flex-align: center; align-items: center; } + +.items-baseline { -webkit-box-align: baseline; -ms-flex-align: baseline; align-items: baseline; } + +.items-stretch { -webkit-box-align: stretch; -ms-flex-align: stretch; align-items: stretch; } + +.self-start { -ms-flex-item-align: start; align-self: flex-start; } + +.self-end { -ms-flex-item-align: end; align-self: flex-end; } + +.self-center { -ms-flex-item-align: center; -ms-grid-row-align: center; align-self: center; } + +.self-baseline { -ms-flex-item-align: baseline; align-self: baseline; } + +.self-stretch { -ms-flex-item-align: stretch; -ms-grid-row-align: stretch; align-self: stretch; } + +.justify-start { -webkit-box-pack: start; -ms-flex-pack: start; justify-content: flex-start; } + +.justify-end { -webkit-box-pack: end; -ms-flex-pack: end; justify-content: flex-end; } + +.justify-center { -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; } + +.justify-between { -webkit-box-pack: justify; -ms-flex-pack: justify; justify-content: space-between; } + +.justify-around { -ms-flex-pack: distribute; justify-content: space-around; } + +.content-start { -ms-flex-line-pack: start; align-content: flex-start; } + +.content-end { -ms-flex-line-pack: end; align-content: flex-end; } + +.content-center { -ms-flex-line-pack: center; align-content: center; } + +.content-between { -ms-flex-line-pack: justify; align-content: space-between; } + +.content-around { -ms-flex-line-pack: distribute; align-content: space-around; } + +.content-stretch { -ms-flex-line-pack: stretch; align-content: stretch; } + +.order-0 { -webkit-box-ordinal-group: 1; -ms-flex-order: 0; order: 0; } + +.order-1 { -webkit-box-ordinal-group: 2; -ms-flex-order: 1; order: 1; } + +.order-2 { -webkit-box-ordinal-group: 3; -ms-flex-order: 2; order: 2; } + +.order-3 { -webkit-box-ordinal-group: 4; -ms-flex-order: 3; order: 3; } + +.order-4 { -webkit-box-ordinal-group: 5; -ms-flex-order: 4; order: 4; } + +.order-5 { -webkit-box-ordinal-group: 6; -ms-flex-order: 5; order: 5; } + +.order-6 { -webkit-box-ordinal-group: 7; -ms-flex-order: 6; order: 6; } + +.order-7 { -webkit-box-ordinal-group: 8; -ms-flex-order: 7; order: 7; } + +.order-8 { -webkit-box-ordinal-group: 9; -ms-flex-order: 8; order: 8; } + +.order-last { -webkit-box-ordinal-group: 100000; -ms-flex-order: 99999; order: 99999; } + +.flex-grow-0 { -webkit-box-flex: 0; -ms-flex-positive: 0; flex-grow: 0; } + +.flex-grow-1 { -webkit-box-flex: 1; -ms-flex-positive: 1; flex-grow: 1; } + +.flex-shrink-0 { -ms-flex-negative: 0; flex-shrink: 0; } + +.flex-shrink-1 { -ms-flex-negative: 1; flex-shrink: 1; } + +@media screen and (min-width: 30em) { + .flex-ns { display: -webkit-box; display: -ms-flexbox; display: flex; } + .inline-flex-ns { display: -webkit-inline-box; display: -ms-inline-flexbox; display: inline-flex; } + .flex-auto-ns { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + min-width: 0; /* 1 */ + min-height: 0; /* 1 */ + } + .flex-none-ns { -webkit-box-flex: 0; -ms-flex: none; flex: none; } + .flex-column-ns { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } + .flex-row-ns { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; } + .flex-wrap-ns { -ms-flex-wrap: wrap; flex-wrap: wrap; } + .flex-nowrap-ns { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } + .flex-wrap-reverse-ns { -ms-flex-wrap: wrap-reverse; flex-wrap: wrap-reverse; } + .flex-column-reverse-ns { -webkit-box-orient: vertical; -webkit-box-direction: reverse; -ms-flex-direction: column-reverse; flex-direction: column-reverse; } + .flex-row-reverse-ns { -webkit-box-orient: horizontal; -webkit-box-direction: reverse; -ms-flex-direction: row-reverse; flex-direction: row-reverse; } + .items-start-ns { -webkit-box-align: start; -ms-flex-align: start; align-items: flex-start; } + .items-end-ns { -webkit-box-align: end; -ms-flex-align: end; align-items: flex-end; } + .items-center-ns { -webkit-box-align: center; -ms-flex-align: center; align-items: center; } + .items-baseline-ns { -webkit-box-align: baseline; -ms-flex-align: baseline; align-items: baseline; } + .items-stretch-ns { -webkit-box-align: stretch; -ms-flex-align: stretch; align-items: stretch; } + + .self-start-ns { -ms-flex-item-align: start; align-self: flex-start; } + .self-end-ns { -ms-flex-item-align: end; align-self: flex-end; } + .self-center-ns { -ms-flex-item-align: center; -ms-grid-row-align: center; align-self: center; } + .self-baseline-ns { -ms-flex-item-align: baseline; align-self: baseline; } + .self-stretch-ns { -ms-flex-item-align: stretch; -ms-grid-row-align: stretch; align-self: stretch; } + + .justify-start-ns { -webkit-box-pack: start; -ms-flex-pack: start; justify-content: flex-start; } + .justify-end-ns { -webkit-box-pack: end; -ms-flex-pack: end; justify-content: flex-end; } + .justify-center-ns { -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; } + .justify-between-ns { -webkit-box-pack: justify; -ms-flex-pack: justify; justify-content: space-between; } + .justify-around-ns { -ms-flex-pack: distribute; justify-content: space-around; } + + .content-start-ns { -ms-flex-line-pack: start; align-content: flex-start; } + .content-end-ns { -ms-flex-line-pack: end; align-content: flex-end; } + .content-center-ns { -ms-flex-line-pack: center; align-content: center; } + .content-between-ns { -ms-flex-line-pack: justify; align-content: space-between; } + .content-around-ns { -ms-flex-line-pack: distribute; align-content: space-around; } + .content-stretch-ns { -ms-flex-line-pack: stretch; align-content: stretch; } + + .order-0-ns { -webkit-box-ordinal-group: 1; -ms-flex-order: 0; order: 0; } + .order-1-ns { -webkit-box-ordinal-group: 2; -ms-flex-order: 1; order: 1; } + .order-2-ns { -webkit-box-ordinal-group: 3; -ms-flex-order: 2; order: 2; } + .order-3-ns { -webkit-box-ordinal-group: 4; -ms-flex-order: 3; order: 3; } + .order-4-ns { -webkit-box-ordinal-group: 5; -ms-flex-order: 4; order: 4; } + .order-5-ns { -webkit-box-ordinal-group: 6; -ms-flex-order: 5; order: 5; } + .order-6-ns { -webkit-box-ordinal-group: 7; -ms-flex-order: 6; order: 6; } + .order-7-ns { -webkit-box-ordinal-group: 8; -ms-flex-order: 7; order: 7; } + .order-8-ns { -webkit-box-ordinal-group: 9; -ms-flex-order: 8; order: 8; } + .order-last-ns { -webkit-box-ordinal-group: 100000; -ms-flex-order: 99999; order: 99999; } + + .flex-grow-0-ns { -webkit-box-flex: 0; -ms-flex-positive: 0; flex-grow: 0; } + .flex-grow-1-ns { -webkit-box-flex: 1; -ms-flex-positive: 1; flex-grow: 1; } + + .flex-shrink-0-ns { -ms-flex-negative: 0; flex-shrink: 0; } + .flex-shrink-1-ns { -ms-flex-negative: 1; flex-shrink: 1; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .flex-m { display: -webkit-box; display: -ms-flexbox; display: flex; } + .inline-flex-m { display: -webkit-inline-box; display: -ms-inline-flexbox; display: inline-flex; } + .flex-auto-m { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + min-width: 0; /* 1 */ + min-height: 0; /* 1 */ + } + .flex-none-m { -webkit-box-flex: 0; -ms-flex: none; flex: none; } + .flex-column-m { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } + .flex-row-m { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; } + .flex-wrap-m { -ms-flex-wrap: wrap; flex-wrap: wrap; } + .flex-nowrap-m { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } + .flex-wrap-reverse-m { -ms-flex-wrap: wrap-reverse; flex-wrap: wrap-reverse; } + .flex-column-reverse-m { -webkit-box-orient: vertical; -webkit-box-direction: reverse; -ms-flex-direction: column-reverse; flex-direction: column-reverse; } + .flex-row-reverse-m { -webkit-box-orient: horizontal; -webkit-box-direction: reverse; -ms-flex-direction: row-reverse; flex-direction: row-reverse; } + .items-start-m { -webkit-box-align: start; -ms-flex-align: start; align-items: flex-start; } + .items-end-m { -webkit-box-align: end; -ms-flex-align: end; align-items: flex-end; } + .items-center-m { -webkit-box-align: center; -ms-flex-align: center; align-items: center; } + .items-baseline-m { -webkit-box-align: baseline; -ms-flex-align: baseline; align-items: baseline; } + .items-stretch-m { -webkit-box-align: stretch; -ms-flex-align: stretch; align-items: stretch; } + + .self-start-m { -ms-flex-item-align: start; align-self: flex-start; } + .self-end-m { -ms-flex-item-align: end; align-self: flex-end; } + .self-center-m { -ms-flex-item-align: center; -ms-grid-row-align: center; align-self: center; } + .self-baseline-m { -ms-flex-item-align: baseline; align-self: baseline; } + .self-stretch-m { -ms-flex-item-align: stretch; -ms-grid-row-align: stretch; align-self: stretch; } + + .justify-start-m { -webkit-box-pack: start; -ms-flex-pack: start; justify-content: flex-start; } + .justify-end-m { -webkit-box-pack: end; -ms-flex-pack: end; justify-content: flex-end; } + .justify-center-m { -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; } + .justify-between-m { -webkit-box-pack: justify; -ms-flex-pack: justify; justify-content: space-between; } + .justify-around-m { -ms-flex-pack: distribute; justify-content: space-around; } + + .content-start-m { -ms-flex-line-pack: start; align-content: flex-start; } + .content-end-m { -ms-flex-line-pack: end; align-content: flex-end; } + .content-center-m { -ms-flex-line-pack: center; align-content: center; } + .content-between-m { -ms-flex-line-pack: justify; align-content: space-between; } + .content-around-m { -ms-flex-line-pack: distribute; align-content: space-around; } + .content-stretch-m { -ms-flex-line-pack: stretch; align-content: stretch; } + + .order-0-m { -webkit-box-ordinal-group: 1; -ms-flex-order: 0; order: 0; } + .order-1-m { -webkit-box-ordinal-group: 2; -ms-flex-order: 1; order: 1; } + .order-2-m { -webkit-box-ordinal-group: 3; -ms-flex-order: 2; order: 2; } + .order-3-m { -webkit-box-ordinal-group: 4; -ms-flex-order: 3; order: 3; } + .order-4-m { -webkit-box-ordinal-group: 5; -ms-flex-order: 4; order: 4; } + .order-5-m { -webkit-box-ordinal-group: 6; -ms-flex-order: 5; order: 5; } + .order-6-m { -webkit-box-ordinal-group: 7; -ms-flex-order: 6; order: 6; } + .order-7-m { -webkit-box-ordinal-group: 8; -ms-flex-order: 7; order: 7; } + .order-8-m { -webkit-box-ordinal-group: 9; -ms-flex-order: 8; order: 8; } + .order-last-m { -webkit-box-ordinal-group: 100000; -ms-flex-order: 99999; order: 99999; } + + .flex-grow-0-m { -webkit-box-flex: 0; -ms-flex-positive: 0; flex-grow: 0; } + .flex-grow-1-m { -webkit-box-flex: 1; -ms-flex-positive: 1; flex-grow: 1; } + + .flex-shrink-0-m { -ms-flex-negative: 0; flex-shrink: 0; } + .flex-shrink-1-m { -ms-flex-negative: 1; flex-shrink: 1; } +} + +@media screen and (min-width: 60em) { + .flex-l { display: -webkit-box; display: -ms-flexbox; display: flex; } + .inline-flex-l { display: -webkit-inline-box; display: -ms-inline-flexbox; display: inline-flex; } + .flex-auto-l { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + min-width: 0; /* 1 */ + min-height: 0; /* 1 */ + } + .flex-none-l { -webkit-box-flex: 0; -ms-flex: none; flex: none; } + .flex-column-l { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } + .flex-row-l { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; } + .flex-wrap-l { -ms-flex-wrap: wrap; flex-wrap: wrap; } + .flex-nowrap-l { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } + .flex-wrap-reverse-l { -ms-flex-wrap: wrap-reverse; flex-wrap: wrap-reverse; } + .flex-column-reverse-l { -webkit-box-orient: vertical; -webkit-box-direction: reverse; -ms-flex-direction: column-reverse; flex-direction: column-reverse; } + .flex-row-reverse-l { -webkit-box-orient: horizontal; -webkit-box-direction: reverse; -ms-flex-direction: row-reverse; flex-direction: row-reverse; } + + .items-start-l { -webkit-box-align: start; -ms-flex-align: start; align-items: flex-start; } + .items-end-l { -webkit-box-align: end; -ms-flex-align: end; align-items: flex-end; } + .items-center-l { -webkit-box-align: center; -ms-flex-align: center; align-items: center; } + .items-baseline-l { -webkit-box-align: baseline; -ms-flex-align: baseline; align-items: baseline; } + .items-stretch-l { -webkit-box-align: stretch; -ms-flex-align: stretch; align-items: stretch; } + + .self-start-l { -ms-flex-item-align: start; align-self: flex-start; } + .self-end-l { -ms-flex-item-align: end; align-self: flex-end; } + .self-center-l { -ms-flex-item-align: center; -ms-grid-row-align: center; align-self: center; } + .self-baseline-l { -ms-flex-item-align: baseline; align-self: baseline; } + .self-stretch-l { -ms-flex-item-align: stretch; -ms-grid-row-align: stretch; align-self: stretch; } + + .justify-start-l { -webkit-box-pack: start; -ms-flex-pack: start; justify-content: flex-start; } + .justify-end-l { -webkit-box-pack: end; -ms-flex-pack: end; justify-content: flex-end; } + .justify-center-l { -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; } + .justify-between-l { -webkit-box-pack: justify; -ms-flex-pack: justify; justify-content: space-between; } + .justify-around-l { -ms-flex-pack: distribute; justify-content: space-around; } + + .content-start-l { -ms-flex-line-pack: start; align-content: flex-start; } + .content-end-l { -ms-flex-line-pack: end; align-content: flex-end; } + .content-center-l { -ms-flex-line-pack: center; align-content: center; } + .content-between-l { -ms-flex-line-pack: justify; align-content: space-between; } + .content-around-l { -ms-flex-line-pack: distribute; align-content: space-around; } + .content-stretch-l { -ms-flex-line-pack: stretch; align-content: stretch; } + + .order-0-l { -webkit-box-ordinal-group: 1; -ms-flex-order: 0; order: 0; } + .order-1-l { -webkit-box-ordinal-group: 2; -ms-flex-order: 1; order: 1; } + .order-2-l { -webkit-box-ordinal-group: 3; -ms-flex-order: 2; order: 2; } + .order-3-l { -webkit-box-ordinal-group: 4; -ms-flex-order: 3; order: 3; } + .order-4-l { -webkit-box-ordinal-group: 5; -ms-flex-order: 4; order: 4; } + .order-5-l { -webkit-box-ordinal-group: 6; -ms-flex-order: 5; order: 5; } + .order-6-l { -webkit-box-ordinal-group: 7; -ms-flex-order: 6; order: 6; } + .order-7-l { -webkit-box-ordinal-group: 8; -ms-flex-order: 7; order: 7; } + .order-8-l { -webkit-box-ordinal-group: 9; -ms-flex-order: 8; order: 8; } + .order-last-l { -webkit-box-ordinal-group: 100000; -ms-flex-order: 99999; order: 99999; } + + .flex-grow-0-l { -webkit-box-flex: 0; -ms-flex-positive: 0; flex-grow: 0; } + .flex-grow-1-l { -webkit-box-flex: 1; -ms-flex-positive: 1; flex-grow: 1; } + + .flex-shrink-0-l { -ms-flex-negative: 0; flex-shrink: 0; } + .flex-shrink-1-l { -ms-flex-negative: 1; flex-shrink: 1; } +} + +/* + + FLOATS + http://tachyons.io/docs/layout/floats/ + + 1. Floated elements are automatically rendered as block level elements. + Setting floats to display inline will fix the double margin bug in + ie6. You know... just in case. + + 2. Don't forget to clearfix your floats with .cf + + Base: + f = float + + Modifiers: + l = left + r = right + n = none + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.fl { float: left; _display: inline; } + +.fr { float: right; _display: inline; } + +.fn { float: none; } + +@media screen and (min-width: 30em) { + .fl-ns { float: left; _display: inline; } + .fr-ns { float: right; _display: inline; } + .fn-ns { float: none; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .fl-m { float: left; _display: inline; } + .fr-m { float: right; _display: inline; } + .fn-m { float: none; } +} + +@media screen and (min-width: 60em) { + .fl-l { float: left; _display: inline; } + .fr-l { float: right; _display: inline; } + .fn-l { float: none; } +} + +/* + + FONT FAMILY GROUPS + Docs: http://tachyons.io/docs/typography/font-family/ + +*/ + +.sans-serif { + font-family: -apple-system, BlinkMacSystemFont, + 'avenir next', avenir, + 'helvetica neue', helvetica, + ubuntu, + roboto, noto, + 'segoe ui', arial, + sans-serif; +} + +.serif { + font-family: georgia, + times, + serif; +} + +.system-sans-serif { + font-family: sans-serif; +} + +.system-serif { + font-family: serif; +} + +/* Monospaced Typefaces (for code) */ + +/* From http://cssfontstack.com */ + +code, .code { + font-family: Consolas, + monaco, + monospace; +} + +.courier { + font-family: 'Courier Next', + courier, + monospace; +} + +/* Sans-Serif Typefaces */ + +.helvetica { + font-family: 'helvetica neue', helvetica, + sans-serif; +} + +.avenir { + font-family: 'avenir next', avenir, + sans-serif; +} + +/* Serif Typefaces */ + +.athelas { + font-family: athelas, + georgia, + serif; +} + +.georgia { + font-family: georgia, + serif; +} + +.times { + font-family: times, + serif; +} + +.bodoni { + font-family: "Bodoni MT", + serif; +} + +.calisto { + font-family: "Calisto MT", + serif; +} + +.garamond { + font-family: garamond, + serif; +} + +.baskerville { + font-family: baskerville, + serif; +} + +/* + + FONT STYLE + Docs: http://tachyons.io/docs/typography/font-style/ + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.i { font-style: italic; } + +.fs-normal { font-style: normal; } + +@media screen and (min-width: 30em) { + .i-ns { font-style: italic; } + .fs-normal-ns { font-style: normal; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .i-m { font-style: italic; } + .fs-normal-m { font-style: normal; } +} + +@media screen and (min-width: 60em) { + .i-l { font-style: italic; } + .fs-normal-l { font-style: normal; } +} + +/* + + FONT WEIGHT + Docs: http://tachyons.io/docs/typography/font-weight/ + + Base + fw = font-weight + + Modifiers: + 1 = literal value 100 + 2 = literal value 200 + 3 = literal value 300 + 4 = literal value 400 + 5 = literal value 500 + 6 = literal value 600 + 7 = literal value 700 + 8 = literal value 800 + 9 = literal value 900 + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.normal { font-weight: normal; } + +.b { font-weight: bold; } + +.fw1 { font-weight: 100; } + +.fw2 { font-weight: 200; } + +.fw3 { font-weight: 300; } + +.fw4 { font-weight: 400; } + +.fw5 { font-weight: 500; } + +.fw6 { font-weight: 600; } + +.fw7 { font-weight: 700; } + +.fw8 { font-weight: 800; } + +.fw9 { font-weight: 900; } + +@media screen and (min-width: 30em) { + .normal-ns { font-weight: normal; } + .b-ns { font-weight: bold; } + .fw1-ns { font-weight: 100; } + .fw2-ns { font-weight: 200; } + .fw3-ns { font-weight: 300; } + .fw4-ns { font-weight: 400; } + .fw5-ns { font-weight: 500; } + .fw6-ns { font-weight: 600; } + .fw7-ns { font-weight: 700; } + .fw8-ns { font-weight: 800; } + .fw9-ns { font-weight: 900; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .normal-m { font-weight: normal; } + .b-m { font-weight: bold; } + .fw1-m { font-weight: 100; } + .fw2-m { font-weight: 200; } + .fw3-m { font-weight: 300; } + .fw4-m { font-weight: 400; } + .fw5-m { font-weight: 500; } + .fw6-m { font-weight: 600; } + .fw7-m { font-weight: 700; } + .fw8-m { font-weight: 800; } + .fw9-m { font-weight: 900; } +} + +@media screen and (min-width: 60em) { + .normal-l { font-weight: normal; } + .b-l { font-weight: bold; } + .fw1-l { font-weight: 100; } + .fw2-l { font-weight: 200; } + .fw3-l { font-weight: 300; } + .fw4-l { font-weight: 400; } + .fw5-l { font-weight: 500; } + .fw6-l { font-weight: 600; } + .fw7-l { font-weight: 700; } + .fw8-l { font-weight: 800; } + .fw9-l { font-weight: 900; } +} + +/* + + FORMS + +*/ + +.input-reset { + -webkit-appearance: none; + -moz-appearance: none; +} + +.button-reset::-moz-focus-inner, +.input-reset::-moz-focus-inner { + border: 0; + padding: 0; +} + +/* + + HEIGHTS + Docs: http://tachyons.io/docs/layout/heights/ + + Base: + h = height + min-h = min-height + min-vh = min-height vertical screen height + vh = vertical screen height + + Modifiers + 1 = 1st step in height scale + 2 = 2nd step in height scale + 3 = 3rd step in height scale + 4 = 4th step in height scale + 5 = 5th step in height scale + + -25 = literal value 25% + -50 = literal value 50% + -75 = literal value 75% + -100 = literal value 100% + + -auto = string value of auto + -inherit = string value of inherit + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +/* Height Scale */ + +.h1 { height: 1rem; } + +.h2 { height: 2rem; } + +.h3 { height: 4rem; } + +.h4 { height: 8rem; } + +.h5 { height: 16rem; } + +/* Height Percentages - Based off of height of parent */ + +.h-25 { height: 25%; } + +.h-50 { height: 50%; } + +.h-75 { height: 75%; } + +.h-100 { height: 100%; } + +.min-h-100 { min-height: 100%; } + +/* Screen Height Percentage */ + +.vh-25 { height: 25vh; } + +.vh-50 { height: 50vh; } + +.vh-75 { height: 75vh; } + +.vh-100 { height: 100vh; } + +.min-vh-100 { min-height: 100vh; } + +/* String Properties */ + +.h-auto { height: auto; } + +.h-inherit { height: inherit; } + +@media screen and (min-width: 30em) { + .h1-ns { height: 1rem; } + .h2-ns { height: 2rem; } + .h3-ns { height: 4rem; } + .h4-ns { height: 8rem; } + .h5-ns { height: 16rem; } + .h-25-ns { height: 25%; } + .h-50-ns { height: 50%; } + .h-75-ns { height: 75%; } + .h-100-ns { height: 100%; } + .min-h-100-ns { min-height: 100%; } + .vh-25-ns { height: 25vh; } + .vh-50-ns { height: 50vh; } + .vh-75-ns { height: 75vh; } + .vh-100-ns { height: 100vh; } + .min-vh-100-ns { min-height: 100vh; } + .h-auto-ns { height: auto; } + .h-inherit-ns { height: inherit; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .h1-m { height: 1rem; } + .h2-m { height: 2rem; } + .h3-m { height: 4rem; } + .h4-m { height: 8rem; } + .h5-m { height: 16rem; } + .h-25-m { height: 25%; } + .h-50-m { height: 50%; } + .h-75-m { height: 75%; } + .h-100-m { height: 100%; } + .min-h-100-m { min-height: 100%; } + .vh-25-m { height: 25vh; } + .vh-50-m { height: 50vh; } + .vh-75-m { height: 75vh; } + .vh-100-m { height: 100vh; } + .min-vh-100-m { min-height: 100vh; } + .h-auto-m { height: auto; } + .h-inherit-m { height: inherit; } +} + +@media screen and (min-width: 60em) { + .h1-l { height: 1rem; } + .h2-l { height: 2rem; } + .h3-l { height: 4rem; } + .h4-l { height: 8rem; } + .h5-l { height: 16rem; } + .h-25-l { height: 25%; } + .h-50-l { height: 50%; } + .h-75-l { height: 75%; } + .h-100-l { height: 100%; } + .min-h-100-l { min-height: 100%; } + .vh-25-l { height: 25vh; } + .vh-50-l { height: 50vh; } + .vh-75-l { height: 75vh; } + .vh-100-l { height: 100vh; } + .min-vh-100-l { min-height: 100vh; } + .h-auto-l { height: auto; } + .h-inherit-l { height: inherit; } +} + +/* + + LETTER SPACING + Docs: http://tachyons.io/docs/typography/tracking/ + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.tracked { letter-spacing: .1em; } + +.tracked-tight { letter-spacing: -.05em; } + +.tracked-mega { letter-spacing: .25em; } + +@media screen and (min-width: 30em) { + .tracked-ns { letter-spacing: .1em; } + .tracked-tight-ns { letter-spacing: -.05em; } + .tracked-mega-ns { letter-spacing: .25em; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .tracked-m { letter-spacing: .1em; } + .tracked-tight-m { letter-spacing: -.05em; } + .tracked-mega-m { letter-spacing: .25em; } +} + +@media screen and (min-width: 60em) { + .tracked-l { letter-spacing: .1em; } + .tracked-tight-l { letter-spacing: -.05em; } + .tracked-mega-l { letter-spacing: .25em; } +} + +/* + + LINE HEIGHT / LEADING + Docs: http://tachyons.io/docs/typography/line-height + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.lh-solid { line-height: 1; } + +.lh-title { line-height: 1.25; } + +.lh-copy { line-height: 1.5; } + +@media screen and (min-width: 30em) { + .lh-solid-ns { line-height: 1; } + .lh-title-ns { line-height: 1.25; } + .lh-copy-ns { line-height: 1.5; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .lh-solid-m { line-height: 1; } + .lh-title-m { line-height: 1.25; } + .lh-copy-m { line-height: 1.5; } +} + +@media screen and (min-width: 60em) { + .lh-solid-l { line-height: 1; } + .lh-title-l { line-height: 1.25; } + .lh-copy-l { line-height: 1.5; } +} + +/* + + LINKS + Docs: http://tachyons.io/docs/elements/links/ + +*/ + +.link { + text-decoration: none; + transition: color .15s ease-in; +} + +.link:link, +.link:visited { + transition: color .15s ease-in; +} + +.link:hover { + transition: color .15s ease-in; +} + +.link:active { + transition: color .15s ease-in; +} + +.link:focus { + transition: color .15s ease-in; + outline: 1px dotted currentColor; +} + +/* + + LISTS + http://tachyons.io/docs/elements/lists/ + +*/ + +.list { list-style-type: none; } + +/* + + MAX WIDTHS + Docs: http://tachyons.io/docs/layout/max-widths/ + + Base: + mw = max-width + + Modifiers + 1 = 1st step in width scale + 2 = 2nd step in width scale + 3 = 3rd step in width scale + 4 = 4th step in width scale + 5 = 5th step in width scale + 6 = 6st step in width scale + 7 = 7nd step in width scale + 8 = 8rd step in width scale + 9 = 9th step in width scale + + -100 = literal value 100% + + -none = string value none + + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +/* Max Width Percentages */ + +.mw-100 { max-width: 100%; } + +/* Max Width Scale */ + +.mw1 { max-width: 1rem; } + +.mw2 { max-width: 2rem; } + +.mw3 { max-width: 4rem; } + +.mw4 { max-width: 8rem; } + +.mw5 { max-width: 16rem; } + +.mw6 { max-width: 32rem; } + +.mw7 { max-width: 48rem; } + +.mw8 { max-width: 64rem; } + +.mw9 { max-width: 96rem; } + +/* Max Width String Properties */ + +.mw-none { max-width: none; } + +@media screen and (min-width: 30em) { + .mw-100-ns { max-width: 100%; } + + .mw1-ns { max-width: 1rem; } + .mw2-ns { max-width: 2rem; } + .mw3-ns { max-width: 4rem; } + .mw4-ns { max-width: 8rem; } + .mw5-ns { max-width: 16rem; } + .mw6-ns { max-width: 32rem; } + .mw7-ns { max-width: 48rem; } + .mw8-ns { max-width: 64rem; } + .mw9-ns { max-width: 96rem; } + + .mw-none-ns { max-width: none; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .mw-100-m { max-width: 100%; } + + .mw1-m { max-width: 1rem; } + .mw2-m { max-width: 2rem; } + .mw3-m { max-width: 4rem; } + .mw4-m { max-width: 8rem; } + .mw5-m { max-width: 16rem; } + .mw6-m { max-width: 32rem; } + .mw7-m { max-width: 48rem; } + .mw8-m { max-width: 64rem; } + .mw9-m { max-width: 96rem; } + + .mw-none-m { max-width: none; } +} + +@media screen and (min-width: 60em) { + .mw-100-l { max-width: 100%; } + + .mw1-l { max-width: 1rem; } + .mw2-l { max-width: 2rem; } + .mw3-l { max-width: 4rem; } + .mw4-l { max-width: 8rem; } + .mw5-l { max-width: 16rem; } + .mw6-l { max-width: 32rem; } + .mw7-l { max-width: 48rem; } + .mw8-l { max-width: 64rem; } + .mw9-l { max-width: 96rem; } + + .mw-none-l { max-width: none; } +} + +/* + + WIDTHS + Docs: http://tachyons.io/docs/layout/widths/ + + Base: + w = width + + Modifiers + 1 = 1st step in width scale + 2 = 2nd step in width scale + 3 = 3rd step in width scale + 4 = 4th step in width scale + 5 = 5th step in width scale + + -10 = literal value 10% + -20 = literal value 20% + -25 = literal value 25% + -30 = literal value 30% + -33 = literal value 33% + -34 = literal value 34% + -40 = literal value 40% + -50 = literal value 50% + -60 = literal value 60% + -70 = literal value 70% + -75 = literal value 75% + -80 = literal value 80% + -90 = literal value 90% + -100 = literal value 100% + + -third = 100% / 3 (Not supported in opera mini or IE8) + -two-thirds = 100% / 1.5 (Not supported in opera mini or IE8) + -auto = string value auto + + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +/* Width Scale */ + +.w1 { width: 1rem; } + +.w2 { width: 2rem; } + +.w3 { width: 4rem; } + +.w4 { width: 8rem; } + +.w5 { width: 16rem; } + +.w-10 { width: 10%; } + +.w-20 { width: 20%; } + +.w-25 { width: 25%; } + +.w-30 { width: 30%; } + +.w-33 { width: 33%; } + +.w-34 { width: 34%; } + +.w-40 { width: 40%; } + +.w-50 { width: 50%; } + +.w-60 { width: 60%; } + +.w-70 { width: 70%; } + +.w-75 { width: 75%; } + +.w-80 { width: 80%; } + +.w-90 { width: 90%; } + +.w-100 { width: 100%; } + +.w-third { width: 33.33333%; } + +.w-two-thirds { width: 66.66667%; } + +.w-auto { width: auto; } + +@media screen and (min-width: 30em) { + .w1-ns { width: 1rem; } + .w2-ns { width: 2rem; } + .w3-ns { width: 4rem; } + .w4-ns { width: 8rem; } + .w5-ns { width: 16rem; } + .w-10-ns { width: 10%; } + .w-20-ns { width: 20%; } + .w-25-ns { width: 25%; } + .w-30-ns { width: 30%; } + .w-33-ns { width: 33%; } + .w-34-ns { width: 34%; } + .w-40-ns { width: 40%; } + .w-50-ns { width: 50%; } + .w-60-ns { width: 60%; } + .w-70-ns { width: 70%; } + .w-75-ns { width: 75%; } + .w-80-ns { width: 80%; } + .w-90-ns { width: 90%; } + .w-100-ns { width: 100%; } + .w-third-ns { width: 33.33333%; } + .w-two-thirds-ns { width: 66.66667%; } + .w-auto-ns { width: auto; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .w1-m { width: 1rem; } + .w2-m { width: 2rem; } + .w3-m { width: 4rem; } + .w4-m { width: 8rem; } + .w5-m { width: 16rem; } + .w-10-m { width: 10%; } + .w-20-m { width: 20%; } + .w-25-m { width: 25%; } + .w-30-m { width: 30%; } + .w-33-m { width: 33%; } + .w-34-m { width: 34%; } + .w-40-m { width: 40%; } + .w-50-m { width: 50%; } + .w-60-m { width: 60%; } + .w-70-m { width: 70%; } + .w-75-m { width: 75%; } + .w-80-m { width: 80%; } + .w-90-m { width: 90%; } + .w-100-m { width: 100%; } + .w-third-m { width: 33.33333%; } + .w-two-thirds-m { width: 66.66667%; } + .w-auto-m { width: auto; } +} + +@media screen and (min-width: 60em) { + .w1-l { width: 1rem; } + .w2-l { width: 2rem; } + .w3-l { width: 4rem; } + .w4-l { width: 8rem; } + .w5-l { width: 16rem; } + .w-10-l { width: 10%; } + .w-20-l { width: 20%; } + .w-25-l { width: 25%; } + .w-30-l { width: 30%; } + .w-33-l { width: 33%; } + .w-34-l { width: 34%; } + .w-40-l { width: 40%; } + .w-50-l { width: 50%; } + .w-60-l { width: 60%; } + .w-70-l { width: 70%; } + .w-75-l { width: 75%; } + .w-80-l { width: 80%; } + .w-90-l { width: 90%; } + .w-100-l { width: 100%; } + .w-third-l { width: 33.33333%; } + .w-two-thirds-l { width: 66.66667%; } + .w-auto-l { width: auto; } +} + +/* + + OVERFLOW + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + + */ + +.overflow-visible { overflow: visible; } + +.overflow-hidden { overflow: hidden; } + +.overflow-scroll { overflow: scroll; } + +.overflow-auto { overflow: auto; } + +.overflow-x-visible { overflow-x: visible; } + +.overflow-x-hidden { overflow-x: hidden; } + +.overflow-x-scroll { overflow-x: scroll; } + +.overflow-x-auto { overflow-x: auto; } + +.overflow-y-visible { overflow-y: visible; } + +.overflow-y-hidden { overflow-y: hidden; } + +.overflow-y-scroll { overflow-y: scroll; } + +.overflow-y-auto { overflow-y: auto; } + +@media screen and (min-width: 30em) { + .overflow-visible-ns { overflow: visible; } + .overflow-hidden-ns { overflow: hidden; } + .overflow-scroll-ns { overflow: scroll; } + .overflow-auto-ns { overflow: auto; } + .overflow-x-visible-ns { overflow-x: visible; } + .overflow-x-hidden-ns { overflow-x: hidden; } + .overflow-x-scroll-ns { overflow-x: scroll; } + .overflow-x-auto-ns { overflow-x: auto; } + + .overflow-y-visible-ns { overflow-y: visible; } + .overflow-y-hidden-ns { overflow-y: hidden; } + .overflow-y-scroll-ns { overflow-y: scroll; } + .overflow-y-auto-ns { overflow-y: auto; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .overflow-visible-m { overflow: visible; } + .overflow-hidden-m { overflow: hidden; } + .overflow-scroll-m { overflow: scroll; } + .overflow-auto-m { overflow: auto; } + + .overflow-x-visible-m { overflow-x: visible; } + .overflow-x-hidden-m { overflow-x: hidden; } + .overflow-x-scroll-m { overflow-x: scroll; } + .overflow-x-auto-m { overflow-x: auto; } + + .overflow-y-visible-m { overflow-y: visible; } + .overflow-y-hidden-m { overflow-y: hidden; } + .overflow-y-scroll-m { overflow-y: scroll; } + .overflow-y-auto-m { overflow-y: auto; } +} + +@media screen and (min-width: 60em) { + .overflow-visible-l { overflow: visible; } + .overflow-hidden-l { overflow: hidden; } + .overflow-scroll-l { overflow: scroll; } + .overflow-auto-l { overflow: auto; } + + .overflow-x-visible-l { overflow-x: visible; } + .overflow-x-hidden-l { overflow-x: hidden; } + .overflow-x-scroll-l { overflow-x: scroll; } + .overflow-x-auto-l { overflow-x: auto; } + + .overflow-y-visible-l { overflow-y: visible; } + .overflow-y-hidden-l { overflow-y: hidden; } + .overflow-y-scroll-l { overflow-y: scroll; } + .overflow-y-auto-l { overflow-y: auto; } +} + +/* + + POSITIONING + Docs: http://tachyons.io/docs/layout/position/ + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.static { position: static; } + +.relative { position: relative; } + +.absolute { position: absolute; } + +.fixed { position: fixed; } + +@media screen and (min-width: 30em) { + .static-ns { position: static; } + .relative-ns { position: relative; } + .absolute-ns { position: absolute; } + .fixed-ns { position: fixed; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .static-m { position: static; } + .relative-m { position: relative; } + .absolute-m { position: absolute; } + .fixed-m { position: fixed; } +} + +@media screen and (min-width: 60em) { + .static-l { position: static; } + .relative-l { position: relative; } + .absolute-l { position: absolute; } + .fixed-l { position: fixed; } +} + +/* + + OPACITY + Docs: http://tachyons.io/docs/themes/opacity/ + +*/ + +.o-100 { opacity: 1; } + +.o-90 { opacity: .9; } + +.o-80 { opacity: .8; } + +.o-70 { opacity: .7; } + +.o-60 { opacity: .6; } + +.o-50 { opacity: .5; } + +.o-40 { opacity: .4; } + +.o-30 { opacity: .3; } + +.o-20 { opacity: .2; } + +.o-10 { opacity: .1; } + +.o-05 { opacity: .05; } + +.o-025 { opacity: .025; } + +.o-0 { opacity: 0; } + +/* + + ROTATIONS + +*/ + +.rotate-45 { -webkit-transform: rotate(45deg); transform: rotate(45deg); } + +.rotate-90 { -webkit-transform: rotate(90deg); transform: rotate(90deg); } + +.rotate-135 { -webkit-transform: rotate(135deg); transform: rotate(135deg); } + +.rotate-180 { -webkit-transform: rotate(180deg); transform: rotate(180deg); } + +.rotate-225 { -webkit-transform: rotate(225deg); transform: rotate(225deg); } + +.rotate-270 { -webkit-transform: rotate(270deg); transform: rotate(270deg); } + +.rotate-315 { -webkit-transform: rotate(315deg); transform: rotate(315deg); } + +@media screen and (min-width: 30em){ + .rotate-45-ns { -webkit-transform: rotate(45deg); transform: rotate(45deg); } + .rotate-90-ns { -webkit-transform: rotate(90deg); transform: rotate(90deg); } + .rotate-135-ns { -webkit-transform: rotate(135deg); transform: rotate(135deg); } + .rotate-180-ns { -webkit-transform: rotate(180deg); transform: rotate(180deg); } + .rotate-225-ns { -webkit-transform: rotate(225deg); transform: rotate(225deg); } + .rotate-270-ns { -webkit-transform: rotate(270deg); transform: rotate(270deg); } + .rotate-315-ns { -webkit-transform: rotate(315deg); transform: rotate(315deg); } +} + +@media screen and (min-width: 30em) and (max-width: 60em){ + .rotate-45-m { -webkit-transform: rotate(45deg); transform: rotate(45deg); } + .rotate-90-m { -webkit-transform: rotate(90deg); transform: rotate(90deg); } + .rotate-135-m { -webkit-transform: rotate(135deg); transform: rotate(135deg); } + .rotate-180-m { -webkit-transform: rotate(180deg); transform: rotate(180deg); } + .rotate-225-m { -webkit-transform: rotate(225deg); transform: rotate(225deg); } + .rotate-270-m { -webkit-transform: rotate(270deg); transform: rotate(270deg); } + .rotate-315-m { -webkit-transform: rotate(315deg); transform: rotate(315deg); } +} + +@media screen and (min-width: 60em){ + .rotate-45-l { -webkit-transform: rotate(45deg); transform: rotate(45deg); } + .rotate-90-l { -webkit-transform: rotate(90deg); transform: rotate(90deg); } + .rotate-135-l { -webkit-transform: rotate(135deg); transform: rotate(135deg); } + .rotate-180-l { -webkit-transform: rotate(180deg); transform: rotate(180deg); } + .rotate-225-l { -webkit-transform: rotate(225deg); transform: rotate(225deg); } + .rotate-270-l { -webkit-transform: rotate(270deg); transform: rotate(270deg); } + .rotate-315-l { -webkit-transform: rotate(315deg); transform: rotate(315deg); } +} + +/* + + SKINS + Docs: http://tachyons.io/docs/themes/skins/ + + Classes for setting foreground and background colors on elements. + If you haven't declared a border color, but set border on an element, it will + be set to the current text color. + +*/ + +/* Text colors */ + +.black-90 { color: rgba(0, 0, 0, .9); } + +.black-80 { color: rgba(0, 0, 0, .8); } + +.black-70 { color: rgba(0, 0, 0, .7); } + +.black-60 { color: rgba(0, 0, 0, .6); } + +.black-50 { color: rgba(0, 0, 0, .5); } + +.black-40 { color: rgba(0, 0, 0, .4); } + +.black-30 { color: rgba(0, 0, 0, .3); } + +.black-20 { color: rgba(0, 0, 0, .2); } + +.black-10 { color: rgba(0, 0, 0, .1); } + +.black-05 { color: rgba(0, 0, 0, .05); } + +.white-90 { color: rgba(255, 255, 255, .9); } + +.white-80 { color: rgba(255, 255, 255, .8); } + +.white-70 { color: rgba(255, 255, 255, .7); } + +.white-60 { color: rgba(255, 255, 255, .6); } + +.white-50 { color: rgba(255, 255, 255, .5); } + +.white-40 { color: rgba(255, 255, 255, .4); } + +.white-30 { color: rgba(255, 255, 255, .3); } + +.white-20 { color: rgba(255, 255, 255, .2); } + +.white-10 { color: rgba(255, 255, 255, .1); } + +.black { color: #000; } + +.near-black { color: #111; } + +.dark-gray { color: #333; } + +.mid-gray { color: #555; } + +.gray { color: #777; } + +.silver { color: #999; } + +.light-silver { color: #aaa; } + +.moon-gray { color: #ccc; } + +.light-gray { color: #eee; } + +.near-white { color: #f4f4f4; } + +.white { color: #fff; } + +.dark-red { color: #e7040f; } + +.red { color: #ff4136; } + +.light-red { color: #ff725c; } + +.orange { color: #ff6300; } + +.gold { color: #ffb700; } + +.yellow { color: #ffd700; } + +.light-yellow { color: #fbf1a9; } + +.purple { color: #5e2ca5; } + +.light-purple { color: #a463f2; } + +.dark-pink { color: #d5008f; } + +.hot-pink { color: #ff41b4; } + +.pink { color: #ff80cc; } + +.light-pink { color: #ffa3d7; } + +.dark-green { color: #137752; } + +.green { color: #19a974; } + +.light-green { color: #9eebcf; } + +.navy { color: #001b44; } + +.dark-blue { color: #00449e; } + +.blue { color: #357edd; } + +.light-blue { color: #96ccff; } + +.lightest-blue { color: #cdecff; } + +.washed-blue { color: #f6fffe; } + +.washed-green { color: #e8fdf5; } + +.washed-yellow { color: #fffceb; } + +.washed-red { color: #ffdfdf; } + +.color-inherit { color: inherit; } + +.bg-black-90 { background-color: rgba(0, 0, 0, .9); } + +.bg-black-80 { background-color: rgba(0, 0, 0, .8); } + +.bg-black-70 { background-color: rgba(0, 0, 0, .7); } + +.bg-black-60 { background-color: rgba(0, 0, 0, .6); } + +.bg-black-50 { background-color: rgba(0, 0, 0, .5); } + +.bg-black-40 { background-color: rgba(0, 0, 0, .4); } + +.bg-black-30 { background-color: rgba(0, 0, 0, .3); } + +.bg-black-20 { background-color: rgba(0, 0, 0, .2); } + +.bg-black-10 { background-color: rgba(0, 0, 0, .1); } + +.bg-black-05 { background-color: rgba(0, 0, 0, .05); } + +.bg-white-90 { background-color: rgba(255, 255, 255, .9); } + +.bg-white-80 { background-color: rgba(255, 255, 255, .8); } + +.bg-white-70 { background-color: rgba(255, 255, 255, .7); } + +.bg-white-60 { background-color: rgba(255, 255, 255, .6); } + +.bg-white-50 { background-color: rgba(255, 255, 255, .5); } + +.bg-white-40 { background-color: rgba(255, 255, 255, .4); } + +.bg-white-30 { background-color: rgba(255, 255, 255, .3); } + +.bg-white-20 { background-color: rgba(255, 255, 255, .2); } + +.bg-white-10 { background-color: rgba(255, 255, 255, .1); } + +/* Background colors */ + +.bg-black { background-color: #000; } + +.bg-near-black { background-color: #111; } + +.bg-dark-gray { background-color: #333; } + +.bg-mid-gray { background-color: #555; } + +.bg-gray { background-color: #777; } + +.bg-silver { background-color: #999; } + +.bg-light-silver { background-color: #aaa; } + +.bg-moon-gray { background-color: #ccc; } + +.bg-light-gray { background-color: #eee; } + +.bg-near-white { background-color: #f4f4f4; } + +.bg-white { background-color: #fff; } + +.bg-transparent { background-color: transparent; } + +.bg-dark-red { background-color: #e7040f; } + +.bg-red { background-color: #ff4136; } + +.bg-light-red { background-color: #ff725c; } + +.bg-orange { background-color: #ff6300; } + +.bg-gold { background-color: #ffb700; } + +.bg-yellow { background-color: #ffd700; } + +.bg-light-yellow { background-color: #fbf1a9; } + +.bg-purple { background-color: #5e2ca5; } + +.bg-light-purple { background-color: #a463f2; } + +.bg-dark-pink { background-color: #d5008f; } + +.bg-hot-pink { background-color: #ff41b4; } + +.bg-pink { background-color: #ff80cc; } + +.bg-light-pink { background-color: #ffa3d7; } + +.bg-dark-green { background-color: #137752; } + +.bg-green { background-color: #19a974; } + +.bg-light-green { background-color: #9eebcf; } + +.bg-navy { background-color: #001b44; } + +.bg-dark-blue { background-color: #00449e; } + +.bg-blue { background-color: #357edd; } + +.bg-light-blue { background-color: #96ccff; } + +.bg-lightest-blue { background-color: #cdecff; } + +.bg-washed-blue { background-color: #f6fffe; } + +.bg-washed-green { background-color: #e8fdf5; } + +.bg-washed-yellow { background-color: #fffceb; } + +.bg-washed-red { background-color: #ffdfdf; } + +.bg-inherit { background-color: inherit; } + +/* + + SKINS:PSEUDO + + Customize the color of an element when + it is focused or hovered over. + + */ + +.hover-black:hover, +.hover-black:focus { color: #000; } + +.hover-near-black:hover, +.hover-near-black:focus { color: #111; } + +.hover-dark-gray:hover, +.hover-dark-gray:focus { color: #333; } + +.hover-mid-gray:hover, +.hover-mid-gray:focus { color: #555; } + +.hover-gray:hover, +.hover-gray:focus { color: #777; } + +.hover-silver:hover, +.hover-silver:focus { color: #999; } + +.hover-light-silver:hover, +.hover-light-silver:focus { color: #aaa; } + +.hover-moon-gray:hover, +.hover-moon-gray:focus { color: #ccc; } + +.hover-light-gray:hover, +.hover-light-gray:focus { color: #eee; } + +.hover-near-white:hover, +.hover-near-white:focus { color: #f4f4f4; } + +.hover-white:hover, +.hover-white:focus { color: #fff; } + +.hover-black-90:hover, +.hover-black-90:focus { color: rgba(0, 0, 0, .9); } + +.hover-black-80:hover, +.hover-black-80:focus { color: rgba(0, 0, 0, .8); } + +.hover-black-70:hover, +.hover-black-70:focus { color: rgba(0, 0, 0, .7); } + +.hover-black-60:hover, +.hover-black-60:focus { color: rgba(0, 0, 0, .6); } + +.hover-black-50:hover, +.hover-black-50:focus { color: rgba(0, 0, 0, .5); } + +.hover-black-40:hover, +.hover-black-40:focus { color: rgba(0, 0, 0, .4); } + +.hover-black-30:hover, +.hover-black-30:focus { color: rgba(0, 0, 0, .3); } + +.hover-black-20:hover, +.hover-black-20:focus { color: rgba(0, 0, 0, .2); } + +.hover-black-10:hover, +.hover-black-10:focus { color: rgba(0, 0, 0, .1); } + +.hover-white-90:hover, +.hover-white-90:focus { color: rgba(255, 255, 255, .9); } + +.hover-white-80:hover, +.hover-white-80:focus { color: rgba(255, 255, 255, .8); } + +.hover-white-70:hover, +.hover-white-70:focus { color: rgba(255, 255, 255, .7); } + +.hover-white-60:hover, +.hover-white-60:focus { color: rgba(255, 255, 255, .6); } + +.hover-white-50:hover, +.hover-white-50:focus { color: rgba(255, 255, 255, .5); } + +.hover-white-40:hover, +.hover-white-40:focus { color: rgba(255, 255, 255, .4); } + +.hover-white-30:hover, +.hover-white-30:focus { color: rgba(255, 255, 255, .3); } + +.hover-white-20:hover, +.hover-white-20:focus { color: rgba(255, 255, 255, .2); } + +.hover-white-10:hover, +.hover-white-10:focus { color: rgba(255, 255, 255, .1); } + +.hover-inherit:hover, +.hover-inherit:focus { color: inherit; } + +.hover-bg-black:hover, +.hover-bg-black:focus { background-color: #000; } + +.hover-bg-near-black:hover, +.hover-bg-near-black:focus { background-color: #111; } + +.hover-bg-dark-gray:hover, +.hover-bg-dark-gray:focus { background-color: #333; } + +.hover-bg-mid-gray:hover, +.hover-bg-mid-gray:focus { background-color: #555; } + +.hover-bg-gray:hover, +.hover-bg-gray:focus { background-color: #777; } + +.hover-bg-silver:hover, +.hover-bg-silver:focus { background-color: #999; } + +.hover-bg-light-silver:hover, +.hover-bg-light-silver:focus { background-color: #aaa; } + +.hover-bg-moon-gray:hover, +.hover-bg-moon-gray:focus { background-color: #ccc; } + +.hover-bg-light-gray:hover, +.hover-bg-light-gray:focus { background-color: #eee; } + +.hover-bg-near-white:hover, +.hover-bg-near-white:focus { background-color: #f4f4f4; } + +.hover-bg-white:hover, +.hover-bg-white:focus { background-color: #fff; } + +.hover-bg-transparent:hover, +.hover-bg-transparent:focus { background-color: transparent; } + +.hover-bg-black-90:hover, +.hover-bg-black-90:focus { background-color: rgba(0, 0, 0, .9); } + +.hover-bg-black-80:hover, +.hover-bg-black-80:focus { background-color: rgba(0, 0, 0, .8); } + +.hover-bg-black-70:hover, +.hover-bg-black-70:focus { background-color: rgba(0, 0, 0, .7); } + +.hover-bg-black-60:hover, +.hover-bg-black-60:focus { background-color: rgba(0, 0, 0, .6); } + +.hover-bg-black-50:hover, +.hover-bg-black-50:focus { background-color: rgba(0, 0, 0, .5); } + +.hover-bg-black-40:hover, +.hover-bg-black-40:focus { background-color: rgba(0, 0, 0, .4); } + +.hover-bg-black-30:hover, +.hover-bg-black-30:focus { background-color: rgba(0, 0, 0, .3); } + +.hover-bg-black-20:hover, +.hover-bg-black-20:focus { background-color: rgba(0, 0, 0, .2); } + +.hover-bg-black-10:hover, +.hover-bg-black-10:focus { background-color: rgba(0, 0, 0, .1); } + +.hover-bg-white-90:hover, +.hover-bg-white-90:focus { background-color: rgba(255, 255, 255, .9); } + +.hover-bg-white-80:hover, +.hover-bg-white-80:focus { background-color: rgba(255, 255, 255, .8); } + +.hover-bg-white-70:hover, +.hover-bg-white-70:focus { background-color: rgba(255, 255, 255, .7); } + +.hover-bg-white-60:hover, +.hover-bg-white-60:focus { background-color: rgba(255, 255, 255, .6); } + +.hover-bg-white-50:hover, +.hover-bg-white-50:focus { background-color: rgba(255, 255, 255, .5); } + +.hover-bg-white-40:hover, +.hover-bg-white-40:focus { background-color: rgba(255, 255, 255, .4); } + +.hover-bg-white-30:hover, +.hover-bg-white-30:focus { background-color: rgba(255, 255, 255, .3); } + +.hover-bg-white-20:hover, +.hover-bg-white-20:focus { background-color: rgba(255, 255, 255, .2); } + +.hover-bg-white-10:hover, +.hover-bg-white-10:focus { background-color: rgba(255, 255, 255, .1); } + +.hover-dark-red:hover, +.hover-dark-red:focus { color: #e7040f; } + +.hover-red:hover, +.hover-red:focus { color: #ff4136; } + +.hover-light-red:hover, +.hover-light-red:focus { color: #ff725c; } + +.hover-orange:hover, +.hover-orange:focus { color: #ff6300; } + +.hover-gold:hover, +.hover-gold:focus { color: #ffb700; } + +.hover-yellow:hover, +.hover-yellow:focus { color: #ffd700; } + +.hover-light-yellow:hover, +.hover-light-yellow:focus { color: #fbf1a9; } + +.hover-purple:hover, +.hover-purple:focus { color: #5e2ca5; } + +.hover-light-purple:hover, +.hover-light-purple:focus { color: #a463f2; } + +.hover-dark-pink:hover, +.hover-dark-pink:focus { color: #d5008f; } + +.hover-hot-pink:hover, +.hover-hot-pink:focus { color: #ff41b4; } + +.hover-pink:hover, +.hover-pink:focus { color: #ff80cc; } + +.hover-light-pink:hover, +.hover-light-pink:focus { color: #ffa3d7; } + +.hover-dark-green:hover, +.hover-dark-green:focus { color: #137752; } + +.hover-green:hover, +.hover-green:focus { color: #19a974; } + +.hover-light-green:hover, +.hover-light-green:focus { color: #9eebcf; } + +.hover-navy:hover, +.hover-navy:focus { color: #001b44; } + +.hover-dark-blue:hover, +.hover-dark-blue:focus { color: #00449e; } + +.hover-blue:hover, +.hover-blue:focus { color: #357edd; } + +.hover-light-blue:hover, +.hover-light-blue:focus { color: #96ccff; } + +.hover-lightest-blue:hover, +.hover-lightest-blue:focus { color: #cdecff; } + +.hover-washed-blue:hover, +.hover-washed-blue:focus { color: #f6fffe; } + +.hover-washed-green:hover, +.hover-washed-green:focus { color: #e8fdf5; } + +.hover-washed-yellow:hover, +.hover-washed-yellow:focus { color: #fffceb; } + +.hover-washed-red:hover, +.hover-washed-red:focus { color: #ffdfdf; } + +.hover-bg-dark-red:hover, +.hover-bg-dark-red:focus { background-color: #e7040f; } + +.hover-bg-red:hover, +.hover-bg-red:focus { background-color: #ff4136; } + +.hover-bg-light-red:hover, +.hover-bg-light-red:focus { background-color: #ff725c; } + +.hover-bg-orange:hover, +.hover-bg-orange:focus { background-color: #ff6300; } + +.hover-bg-gold:hover, +.hover-bg-gold:focus { background-color: #ffb700; } + +.hover-bg-yellow:hover, +.hover-bg-yellow:focus { background-color: #ffd700; } + +.hover-bg-light-yellow:hover, +.hover-bg-light-yellow:focus { background-color: #fbf1a9; } + +.hover-bg-purple:hover, +.hover-bg-purple:focus { background-color: #5e2ca5; } + +.hover-bg-light-purple:hover, +.hover-bg-light-purple:focus { background-color: #a463f2; } + +.hover-bg-dark-pink:hover, +.hover-bg-dark-pink:focus { background-color: #d5008f; } + +.hover-bg-hot-pink:hover, +.hover-bg-hot-pink:focus { background-color: #ff41b4; } + +.hover-bg-pink:hover, +.hover-bg-pink:focus { background-color: #ff80cc; } + +.hover-bg-light-pink:hover, +.hover-bg-light-pink:focus { background-color: #ffa3d7; } + +.hover-bg-dark-green:hover, +.hover-bg-dark-green:focus { background-color: #137752; } + +.hover-bg-green:hover, +.hover-bg-green:focus { background-color: #19a974; } + +.hover-bg-light-green:hover, +.hover-bg-light-green:focus { background-color: #9eebcf; } + +.hover-bg-navy:hover, +.hover-bg-navy:focus { background-color: #001b44; } + +.hover-bg-dark-blue:hover, +.hover-bg-dark-blue:focus { background-color: #00449e; } + +.hover-bg-blue:hover, +.hover-bg-blue:focus { background-color: #357edd; } + +.hover-bg-light-blue:hover, +.hover-bg-light-blue:focus { background-color: #96ccff; } + +.hover-bg-lightest-blue:hover, +.hover-bg-lightest-blue:focus { background-color: #cdecff; } + +.hover-bg-washed-blue:hover, +.hover-bg-washed-blue:focus { background-color: #f6fffe; } + +.hover-bg-washed-green:hover, +.hover-bg-washed-green:focus { background-color: #e8fdf5; } + +.hover-bg-washed-yellow:hover, +.hover-bg-washed-yellow:focus { background-color: #fffceb; } + +.hover-bg-washed-red:hover, +.hover-bg-washed-red:focus { background-color: #ffdfdf; } + +.hover-bg-inherit:hover, +.hover-bg-inherit:focus { background-color: inherit; } + +/* Variables */ + +/* + SPACING + Docs: http://tachyons.io/docs/layout/spacing/ + + An eight step powers of two scale ranging from 0 to 16rem. + + Base: + p = padding + m = margin + + Modifiers: + a = all + h = horizontal + v = vertical + t = top + r = right + b = bottom + l = left + + 0 = none + 1 = 1st step in spacing scale + 2 = 2nd step in spacing scale + 3 = 3rd step in spacing scale + 4 = 4th step in spacing scale + 5 = 5th step in spacing scale + 6 = 6th step in spacing scale + 7 = 7th step in spacing scale + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.pa0 { padding: 0; } + +.pa1 { padding: .25rem; } + +.pa2 { padding: .5rem; } + +.pa3 { padding: 1rem; } + +.pa4 { padding: 2rem; } + +.pa5 { padding: 4rem; } + +.pa6 { padding: 8rem; } + +.pa7 { padding: 16rem; } + +.pl0 { padding-left: 0; } + +.pl1 { padding-left: .25rem; } + +.pl2 { padding-left: .5rem; } + +.pl3 { padding-left: 1rem; } + +.pl4 { padding-left: 2rem; } + +.pl5 { padding-left: 4rem; } + +.pl6 { padding-left: 8rem; } + +.pl7 { padding-left: 16rem; } + +.pr0 { padding-right: 0; } + +.pr1 { padding-right: .25rem; } + +.pr2 { padding-right: .5rem; } + +.pr3 { padding-right: 1rem; } + +.pr4 { padding-right: 2rem; } + +.pr5 { padding-right: 4rem; } + +.pr6 { padding-right: 8rem; } + +.pr7 { padding-right: 16rem; } + +.pb0 { padding-bottom: 0; } + +.pb1 { padding-bottom: .25rem; } + +.pb2 { padding-bottom: .5rem; } + +.pb3 { padding-bottom: 1rem; } + +.pb4 { padding-bottom: 2rem; } + +.pb5 { padding-bottom: 4rem; } + +.pb6 { padding-bottom: 8rem; } + +.pb7 { padding-bottom: 16rem; } + +.pt0 { padding-top: 0; } + +.pt1 { padding-top: .25rem; } + +.pt2 { padding-top: .5rem; } + +.pt3 { padding-top: 1rem; } + +.pt4 { padding-top: 2rem; } + +.pt5 { padding-top: 4rem; } + +.pt6 { padding-top: 8rem; } + +.pt7 { padding-top: 16rem; } + +.pv0 { + padding-top: 0; + padding-bottom: 0; +} + +.pv1 { + padding-top: .25rem; + padding-bottom: .25rem; +} + +.pv2 { + padding-top: .5rem; + padding-bottom: .5rem; +} + +.pv3 { + padding-top: 1rem; + padding-bottom: 1rem; +} + +.pv4 { + padding-top: 2rem; + padding-bottom: 2rem; +} + +.pv5 { + padding-top: 4rem; + padding-bottom: 4rem; +} + +.pv6 { + padding-top: 8rem; + padding-bottom: 8rem; +} + +.pv7 { + padding-top: 16rem; + padding-bottom: 16rem; +} + +.ph0 { + padding-left: 0; + padding-right: 0; +} + +.ph1 { + padding-left: .25rem; + padding-right: .25rem; +} + +.ph2 { + padding-left: .5rem; + padding-right: .5rem; +} + +.ph3 { + padding-left: 1rem; + padding-right: 1rem; +} + +.ph4 { + padding-left: 2rem; + padding-right: 2rem; +} + +.ph5 { + padding-left: 4rem; + padding-right: 4rem; +} + +.ph6 { + padding-left: 8rem; + padding-right: 8rem; +} + +.ph7 { + padding-left: 16rem; + padding-right: 16rem; +} + +.ma0 { margin: 0; } + +.ma1 { margin: .25rem; } + +.ma2 { margin: .5rem; } + +.ma3 { margin: 1rem; } + +.ma4 { margin: 2rem; } + +.ma5 { margin: 4rem; } + +.ma6 { margin: 8rem; } + +.ma7 { margin: 16rem; } + +.ml0 { margin-left: 0; } + +.ml1 { margin-left: .25rem; } + +.ml2 { margin-left: .5rem; } + +.ml3 { margin-left: 1rem; } + +.ml4 { margin-left: 2rem; } + +.ml5 { margin-left: 4rem; } + +.ml6 { margin-left: 8rem; } + +.ml7 { margin-left: 16rem; } + +.mr0 { margin-right: 0; } + +.mr1 { margin-right: .25rem; } + +.mr2 { margin-right: .5rem; } + +.mr3 { margin-right: 1rem; } + +.mr4 { margin-right: 2rem; } + +.mr5 { margin-right: 4rem; } + +.mr6 { margin-right: 8rem; } + +.mr7 { margin-right: 16rem; } + +.mb0 { margin-bottom: 0; } + +.mb1 { margin-bottom: .25rem; } + +.mb2 { margin-bottom: .5rem; } + +.mb3 { margin-bottom: 1rem; } + +.mb4 { margin-bottom: 2rem; } + +.mb5 { margin-bottom: 4rem; } + +.mb6 { margin-bottom: 8rem; } + +.mb7 { margin-bottom: 16rem; } + +.mt0 { margin-top: 0; } + +.mt1 { margin-top: .25rem; } + +.mt2 { margin-top: .5rem; } + +.mt3 { margin-top: 1rem; } + +.mt4 { margin-top: 2rem; } + +.mt5 { margin-top: 4rem; } + +.mt6 { margin-top: 8rem; } + +.mt7 { margin-top: 16rem; } + +.mv0 { + margin-top: 0; + margin-bottom: 0; +} + +.mv1 { + margin-top: .25rem; + margin-bottom: .25rem; +} + +.mv2 { + margin-top: .5rem; + margin-bottom: .5rem; +} + +.mv3 { + margin-top: 1rem; + margin-bottom: 1rem; +} + +.mv4 { + margin-top: 2rem; + margin-bottom: 2rem; +} + +.mv5 { + margin-top: 4rem; + margin-bottom: 4rem; +} + +.mv6 { + margin-top: 8rem; + margin-bottom: 8rem; +} + +.mv7 { + margin-top: 16rem; + margin-bottom: 16rem; +} + +.mh0 { + margin-left: 0; + margin-right: 0; +} + +.mh1 { + margin-left: .25rem; + margin-right: .25rem; +} + +.mh2 { + margin-left: .5rem; + margin-right: .5rem; +} + +.mh3 { + margin-left: 1rem; + margin-right: 1rem; +} + +.mh4 { + margin-left: 2rem; + margin-right: 2rem; +} + +.mh5 { + margin-left: 4rem; + margin-right: 4rem; +} + +.mh6 { + margin-left: 8rem; + margin-right: 8rem; +} + +.mh7 { + margin-left: 16rem; + margin-right: 16rem; +} + +@media screen and (min-width: 30em) { + .pa0-ns { padding: 0; } + .pa1-ns { padding: .25rem; } + .pa2-ns { padding: .5rem; } + .pa3-ns { padding: 1rem; } + .pa4-ns { padding: 2rem; } + .pa5-ns { padding: 4rem; } + .pa6-ns { padding: 8rem; } + .pa7-ns { padding: 16rem; } + + .pl0-ns { padding-left: 0; } + .pl1-ns { padding-left: .25rem; } + .pl2-ns { padding-left: .5rem; } + .pl3-ns { padding-left: 1rem; } + .pl4-ns { padding-left: 2rem; } + .pl5-ns { padding-left: 4rem; } + .pl6-ns { padding-left: 8rem; } + .pl7-ns { padding-left: 16rem; } + + .pr0-ns { padding-right: 0; } + .pr1-ns { padding-right: .25rem; } + .pr2-ns { padding-right: .5rem; } + .pr3-ns { padding-right: 1rem; } + .pr4-ns { padding-right: 2rem; } + .pr5-ns { padding-right: 4rem; } + .pr6-ns { padding-right: 8rem; } + .pr7-ns { padding-right: 16rem; } + + .pb0-ns { padding-bottom: 0; } + .pb1-ns { padding-bottom: .25rem; } + .pb2-ns { padding-bottom: .5rem; } + .pb3-ns { padding-bottom: 1rem; } + .pb4-ns { padding-bottom: 2rem; } + .pb5-ns { padding-bottom: 4rem; } + .pb6-ns { padding-bottom: 8rem; } + .pb7-ns { padding-bottom: 16rem; } + + .pt0-ns { padding-top: 0; } + .pt1-ns { padding-top: .25rem; } + .pt2-ns { padding-top: .5rem; } + .pt3-ns { padding-top: 1rem; } + .pt4-ns { padding-top: 2rem; } + .pt5-ns { padding-top: 4rem; } + .pt6-ns { padding-top: 8rem; } + .pt7-ns { padding-top: 16rem; } + + .pv0-ns { + padding-top: 0; + padding-bottom: 0; + } + .pv1-ns { + padding-top: .25rem; + padding-bottom: .25rem; + } + .pv2-ns { + padding-top: .5rem; + padding-bottom: .5rem; + } + .pv3-ns { + padding-top: 1rem; + padding-bottom: 1rem; + } + .pv4-ns { + padding-top: 2rem; + padding-bottom: 2rem; + } + .pv5-ns { + padding-top: 4rem; + padding-bottom: 4rem; + } + .pv6-ns { + padding-top: 8rem; + padding-bottom: 8rem; + } + .pv7-ns { + padding-top: 16rem; + padding-bottom: 16rem; + } + .ph0-ns { + padding-left: 0; + padding-right: 0; + } + .ph1-ns { + padding-left: .25rem; + padding-right: .25rem; + } + .ph2-ns { + padding-left: .5rem; + padding-right: .5rem; + } + .ph3-ns { + padding-left: 1rem; + padding-right: 1rem; + } + .ph4-ns { + padding-left: 2rem; + padding-right: 2rem; + } + .ph5-ns { + padding-left: 4rem; + padding-right: 4rem; + } + .ph6-ns { + padding-left: 8rem; + padding-right: 8rem; + } + .ph7-ns { + padding-left: 16rem; + padding-right: 16rem; + } + + .ma0-ns { margin: 0; } + .ma1-ns { margin: .25rem; } + .ma2-ns { margin: .5rem; } + .ma3-ns { margin: 1rem; } + .ma4-ns { margin: 2rem; } + .ma5-ns { margin: 4rem; } + .ma6-ns { margin: 8rem; } + .ma7-ns { margin: 16rem; } + + .ml0-ns { margin-left: 0; } + .ml1-ns { margin-left: .25rem; } + .ml2-ns { margin-left: .5rem; } + .ml3-ns { margin-left: 1rem; } + .ml4-ns { margin-left: 2rem; } + .ml5-ns { margin-left: 4rem; } + .ml6-ns { margin-left: 8rem; } + .ml7-ns { margin-left: 16rem; } + + .mr0-ns { margin-right: 0; } + .mr1-ns { margin-right: .25rem; } + .mr2-ns { margin-right: .5rem; } + .mr3-ns { margin-right: 1rem; } + .mr4-ns { margin-right: 2rem; } + .mr5-ns { margin-right: 4rem; } + .mr6-ns { margin-right: 8rem; } + .mr7-ns { margin-right: 16rem; } + + .mb0-ns { margin-bottom: 0; } + .mb1-ns { margin-bottom: .25rem; } + .mb2-ns { margin-bottom: .5rem; } + .mb3-ns { margin-bottom: 1rem; } + .mb4-ns { margin-bottom: 2rem; } + .mb5-ns { margin-bottom: 4rem; } + .mb6-ns { margin-bottom: 8rem; } + .mb7-ns { margin-bottom: 16rem; } + + .mt0-ns { margin-top: 0; } + .mt1-ns { margin-top: .25rem; } + .mt2-ns { margin-top: .5rem; } + .mt3-ns { margin-top: 1rem; } + .mt4-ns { margin-top: 2rem; } + .mt5-ns { margin-top: 4rem; } + .mt6-ns { margin-top: 8rem; } + .mt7-ns { margin-top: 16rem; } + + .mv0-ns { + margin-top: 0; + margin-bottom: 0; + } + .mv1-ns { + margin-top: .25rem; + margin-bottom: .25rem; + } + .mv2-ns { + margin-top: .5rem; + margin-bottom: .5rem; + } + .mv3-ns { + margin-top: 1rem; + margin-bottom: 1rem; + } + .mv4-ns { + margin-top: 2rem; + margin-bottom: 2rem; + } + .mv5-ns { + margin-top: 4rem; + margin-bottom: 4rem; + } + .mv6-ns { + margin-top: 8rem; + margin-bottom: 8rem; + } + .mv7-ns { + margin-top: 16rem; + margin-bottom: 16rem; + } + + .mh0-ns { + margin-left: 0; + margin-right: 0; + } + .mh1-ns { + margin-left: .25rem; + margin-right: .25rem; + } + .mh2-ns { + margin-left: .5rem; + margin-right: .5rem; + } + .mh3-ns { + margin-left: 1rem; + margin-right: 1rem; + } + .mh4-ns { + margin-left: 2rem; + margin-right: 2rem; + } + .mh5-ns { + margin-left: 4rem; + margin-right: 4rem; + } + .mh6-ns { + margin-left: 8rem; + margin-right: 8rem; + } + .mh7-ns { + margin-left: 16rem; + margin-right: 16rem; + } + +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .pa0-m { padding: 0; } + .pa1-m { padding: .25rem; } + .pa2-m { padding: .5rem; } + .pa3-m { padding: 1rem; } + .pa4-m { padding: 2rem; } + .pa5-m { padding: 4rem; } + .pa6-m { padding: 8rem; } + .pa7-m { padding: 16rem; } + + .pl0-m { padding-left: 0; } + .pl1-m { padding-left: .25rem; } + .pl2-m { padding-left: .5rem; } + .pl3-m { padding-left: 1rem; } + .pl4-m { padding-left: 2rem; } + .pl5-m { padding-left: 4rem; } + .pl6-m { padding-left: 8rem; } + .pl7-m { padding-left: 16rem; } + + .pr0-m { padding-right: 0; } + .pr1-m { padding-right: .25rem; } + .pr2-m { padding-right: .5rem; } + .pr3-m { padding-right: 1rem; } + .pr4-m { padding-right: 2rem; } + .pr5-m { padding-right: 4rem; } + .pr6-m { padding-right: 8rem; } + .pr7-m { padding-right: 16rem; } + + .pb0-m { padding-bottom: 0; } + .pb1-m { padding-bottom: .25rem; } + .pb2-m { padding-bottom: .5rem; } + .pb3-m { padding-bottom: 1rem; } + .pb4-m { padding-bottom: 2rem; } + .pb5-m { padding-bottom: 4rem; } + .pb6-m { padding-bottom: 8rem; } + .pb7-m { padding-bottom: 16rem; } + + .pt0-m { padding-top: 0; } + .pt1-m { padding-top: .25rem; } + .pt2-m { padding-top: .5rem; } + .pt3-m { padding-top: 1rem; } + .pt4-m { padding-top: 2rem; } + .pt5-m { padding-top: 4rem; } + .pt6-m { padding-top: 8rem; } + .pt7-m { padding-top: 16rem; } + + .pv0-m { + padding-top: 0; + padding-bottom: 0; + } + .pv1-m { + padding-top: .25rem; + padding-bottom: .25rem; + } + .pv2-m { + padding-top: .5rem; + padding-bottom: .5rem; + } + .pv3-m { + padding-top: 1rem; + padding-bottom: 1rem; + } + .pv4-m { + padding-top: 2rem; + padding-bottom: 2rem; + } + .pv5-m { + padding-top: 4rem; + padding-bottom: 4rem; + } + .pv6-m { + padding-top: 8rem; + padding-bottom: 8rem; + } + .pv7-m { + padding-top: 16rem; + padding-bottom: 16rem; + } + + .ph0-m { + padding-left: 0; + padding-right: 0; + } + .ph1-m { + padding-left: .25rem; + padding-right: .25rem; + } + .ph2-m { + padding-left: .5rem; + padding-right: .5rem; + } + .ph3-m { + padding-left: 1rem; + padding-right: 1rem; + } + .ph4-m { + padding-left: 2rem; + padding-right: 2rem; + } + .ph5-m { + padding-left: 4rem; + padding-right: 4rem; + } + .ph6-m { + padding-left: 8rem; + padding-right: 8rem; + } + .ph7-m { + padding-left: 16rem; + padding-right: 16rem; + } + + .ma0-m { margin: 0; } + .ma1-m { margin: .25rem; } + .ma2-m { margin: .5rem; } + .ma3-m { margin: 1rem; } + .ma4-m { margin: 2rem; } + .ma5-m { margin: 4rem; } + .ma6-m { margin: 8rem; } + .ma7-m { margin: 16rem; } + + .ml0-m { margin-left: 0; } + .ml1-m { margin-left: .25rem; } + .ml2-m { margin-left: .5rem; } + .ml3-m { margin-left: 1rem; } + .ml4-m { margin-left: 2rem; } + .ml5-m { margin-left: 4rem; } + .ml6-m { margin-left: 8rem; } + .ml7-m { margin-left: 16rem; } + + .mr0-m { margin-right: 0; } + .mr1-m { margin-right: .25rem; } + .mr2-m { margin-right: .5rem; } + .mr3-m { margin-right: 1rem; } + .mr4-m { margin-right: 2rem; } + .mr5-m { margin-right: 4rem; } + .mr6-m { margin-right: 8rem; } + .mr7-m { margin-right: 16rem; } + + .mb0-m { margin-bottom: 0; } + .mb1-m { margin-bottom: .25rem; } + .mb2-m { margin-bottom: .5rem; } + .mb3-m { margin-bottom: 1rem; } + .mb4-m { margin-bottom: 2rem; } + .mb5-m { margin-bottom: 4rem; } + .mb6-m { margin-bottom: 8rem; } + .mb7-m { margin-bottom: 16rem; } + + .mt0-m { margin-top: 0; } + .mt1-m { margin-top: .25rem; } + .mt2-m { margin-top: .5rem; } + .mt3-m { margin-top: 1rem; } + .mt4-m { margin-top: 2rem; } + .mt5-m { margin-top: 4rem; } + .mt6-m { margin-top: 8rem; } + .mt7-m { margin-top: 16rem; } + + .mv0-m { + margin-top: 0; + margin-bottom: 0; + } + .mv1-m { + margin-top: .25rem; + margin-bottom: .25rem; + } + .mv2-m { + margin-top: .5rem; + margin-bottom: .5rem; + } + .mv3-m { + margin-top: 1rem; + margin-bottom: 1rem; + } + .mv4-m { + margin-top: 2rem; + margin-bottom: 2rem; + } + .mv5-m { + margin-top: 4rem; + margin-bottom: 4rem; + } + .mv6-m { + margin-top: 8rem; + margin-bottom: 8rem; + } + .mv7-m { + margin-top: 16rem; + margin-bottom: 16rem; + } + + .mh0-m { + margin-left: 0; + margin-right: 0; + } + .mh1-m { + margin-left: .25rem; + margin-right: .25rem; + } + .mh2-m { + margin-left: .5rem; + margin-right: .5rem; + } + .mh3-m { + margin-left: 1rem; + margin-right: 1rem; + } + .mh4-m { + margin-left: 2rem; + margin-right: 2rem; + } + .mh5-m { + margin-left: 4rem; + margin-right: 4rem; + } + .mh6-m { + margin-left: 8rem; + margin-right: 8rem; + } + .mh7-m { + margin-left: 16rem; + margin-right: 16rem; + } + +} + +@media screen and (min-width: 60em) { + .pa0-l { padding: 0; } + .pa1-l { padding: .25rem; } + .pa2-l { padding: .5rem; } + .pa3-l { padding: 1rem; } + .pa4-l { padding: 2rem; } + .pa5-l { padding: 4rem; } + .pa6-l { padding: 8rem; } + .pa7-l { padding: 16rem; } + + .pl0-l { padding-left: 0; } + .pl1-l { padding-left: .25rem; } + .pl2-l { padding-left: .5rem; } + .pl3-l { padding-left: 1rem; } + .pl4-l { padding-left: 2rem; } + .pl5-l { padding-left: 4rem; } + .pl6-l { padding-left: 8rem; } + .pl7-l { padding-left: 16rem; } + + .pr0-l { padding-right: 0; } + .pr1-l { padding-right: .25rem; } + .pr2-l { padding-right: .5rem; } + .pr3-l { padding-right: 1rem; } + .pr4-l { padding-right: 2rem; } + .pr5-l { padding-right: 4rem; } + .pr6-l { padding-right: 8rem; } + .pr7-l { padding-right: 16rem; } + + .pb0-l { padding-bottom: 0; } + .pb1-l { padding-bottom: .25rem; } + .pb2-l { padding-bottom: .5rem; } + .pb3-l { padding-bottom: 1rem; } + .pb4-l { padding-bottom: 2rem; } + .pb5-l { padding-bottom: 4rem; } + .pb6-l { padding-bottom: 8rem; } + .pb7-l { padding-bottom: 16rem; } + + .pt0-l { padding-top: 0; } + .pt1-l { padding-top: .25rem; } + .pt2-l { padding-top: .5rem; } + .pt3-l { padding-top: 1rem; } + .pt4-l { padding-top: 2rem; } + .pt5-l { padding-top: 4rem; } + .pt6-l { padding-top: 8rem; } + .pt7-l { padding-top: 16rem; } + + .pv0-l { + padding-top: 0; + padding-bottom: 0; + } + .pv1-l { + padding-top: .25rem; + padding-bottom: .25rem; + } + .pv2-l { + padding-top: .5rem; + padding-bottom: .5rem; + } + .pv3-l { + padding-top: 1rem; + padding-bottom: 1rem; + } + .pv4-l { + padding-top: 2rem; + padding-bottom: 2rem; + } + .pv5-l { + padding-top: 4rem; + padding-bottom: 4rem; + } + .pv6-l { + padding-top: 8rem; + padding-bottom: 8rem; + } + .pv7-l { + padding-top: 16rem; + padding-bottom: 16rem; + } + + .ph0-l { + padding-left: 0; + padding-right: 0; + } + .ph1-l { + padding-left: .25rem; + padding-right: .25rem; + } + .ph2-l { + padding-left: .5rem; + padding-right: .5rem; + } + .ph3-l { + padding-left: 1rem; + padding-right: 1rem; + } + .ph4-l { + padding-left: 2rem; + padding-right: 2rem; + } + .ph5-l { + padding-left: 4rem; + padding-right: 4rem; + } + .ph6-l { + padding-left: 8rem; + padding-right: 8rem; + } + .ph7-l { + padding-left: 16rem; + padding-right: 16rem; + } + + .ma0-l { margin: 0; } + .ma1-l { margin: .25rem; } + .ma2-l { margin: .5rem; } + .ma3-l { margin: 1rem; } + .ma4-l { margin: 2rem; } + .ma5-l { margin: 4rem; } + .ma6-l { margin: 8rem; } + .ma7-l { margin: 16rem; } + + .ml0-l { margin-left: 0; } + .ml1-l { margin-left: .25rem; } + .ml2-l { margin-left: .5rem; } + .ml3-l { margin-left: 1rem; } + .ml4-l { margin-left: 2rem; } + .ml5-l { margin-left: 4rem; } + .ml6-l { margin-left: 8rem; } + .ml7-l { margin-left: 16rem; } + + .mr0-l { margin-right: 0; } + .mr1-l { margin-right: .25rem; } + .mr2-l { margin-right: .5rem; } + .mr3-l { margin-right: 1rem; } + .mr4-l { margin-right: 2rem; } + .mr5-l { margin-right: 4rem; } + .mr6-l { margin-right: 8rem; } + .mr7-l { margin-right: 16rem; } + + .mb0-l { margin-bottom: 0; } + .mb1-l { margin-bottom: .25rem; } + .mb2-l { margin-bottom: .5rem; } + .mb3-l { margin-bottom: 1rem; } + .mb4-l { margin-bottom: 2rem; } + .mb5-l { margin-bottom: 4rem; } + .mb6-l { margin-bottom: 8rem; } + .mb7-l { margin-bottom: 16rem; } + + .mt0-l { margin-top: 0; } + .mt1-l { margin-top: .25rem; } + .mt2-l { margin-top: .5rem; } + .mt3-l { margin-top: 1rem; } + .mt4-l { margin-top: 2rem; } + .mt5-l { margin-top: 4rem; } + .mt6-l { margin-top: 8rem; } + .mt7-l { margin-top: 16rem; } + + .mv0-l { + margin-top: 0; + margin-bottom: 0; + } + .mv1-l { + margin-top: .25rem; + margin-bottom: .25rem; + } + .mv2-l { + margin-top: .5rem; + margin-bottom: .5rem; + } + .mv3-l { + margin-top: 1rem; + margin-bottom: 1rem; + } + .mv4-l { + margin-top: 2rem; + margin-bottom: 2rem; + } + .mv5-l { + margin-top: 4rem; + margin-bottom: 4rem; + } + .mv6-l { + margin-top: 8rem; + margin-bottom: 8rem; + } + .mv7-l { + margin-top: 16rem; + margin-bottom: 16rem; + } + + .mh0-l { + margin-left: 0; + margin-right: 0; + } + .mh1-l { + margin-left: .25rem; + margin-right: .25rem; + } + .mh2-l { + margin-left: .5rem; + margin-right: .5rem; + } + .mh3-l { + margin-left: 1rem; + margin-right: 1rem; + } + .mh4-l { + margin-left: 2rem; + margin-right: 2rem; + } + .mh5-l { + margin-left: 4rem; + margin-right: 4rem; + } + .mh6-l { + margin-left: 8rem; + margin-right: 8rem; + } + .mh7-l { + margin-left: 16rem; + margin-right: 16rem; + } +} + +/* + NEGATIVE MARGINS + + Base: + n = negative + + Modifiers: + a = all + t = top + r = right + b = bottom + l = left + + 1 = 1st step in spacing scale + 2 = 2nd step in spacing scale + 3 = 3rd step in spacing scale + 4 = 4th step in spacing scale + 5 = 5th step in spacing scale + 6 = 6th step in spacing scale + 7 = 7th step in spacing scale + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.na1 { margin: -0.25rem; } + +.na2 { margin: -0.5rem; } + +.na3 { margin: -1rem; } + +.na4 { margin: -2rem; } + +.na5 { margin: -4rem; } + +.na6 { margin: -8rem; } + +.na7 { margin: -16rem; } + +.nl1 { margin-left: -0.25rem; } + +.nl2 { margin-left: -0.5rem; } + +.nl3 { margin-left: -1rem; } + +.nl4 { margin-left: -2rem; } + +.nl5 { margin-left: -4rem; } + +.nl6 { margin-left: -8rem; } + +.nl7 { margin-left: -16rem; } + +.nr1 { margin-right: -0.25rem; } + +.nr2 { margin-right: -0.5rem; } + +.nr3 { margin-right: -1rem; } + +.nr4 { margin-right: -2rem; } + +.nr5 { margin-right: -4rem; } + +.nr6 { margin-right: -8rem; } + +.nr7 { margin-right: -16rem; } + +.nb1 { margin-bottom: -0.25rem; } + +.nb2 { margin-bottom: -0.5rem; } + +.nb3 { margin-bottom: -1rem; } + +.nb4 { margin-bottom: -2rem; } + +.nb5 { margin-bottom: -4rem; } + +.nb6 { margin-bottom: -8rem; } + +.nb7 { margin-bottom: -16rem; } + +.nt1 { margin-top: -0.25rem; } + +.nt2 { margin-top: -0.5rem; } + +.nt3 { margin-top: -1rem; } + +.nt4 { margin-top: -2rem; } + +.nt5 { margin-top: -4rem; } + +.nt6 { margin-top: -8rem; } + +.nt7 { margin-top: -16rem; } + +@media screen and (min-width: 30em) { + + .na1-ns { margin: -0.25rem; } + .na2-ns { margin: -0.5rem; } + .na3-ns { margin: -1rem; } + .na4-ns { margin: -2rem; } + .na5-ns { margin: -4rem; } + .na6-ns { margin: -8rem; } + .na7-ns { margin: -16rem; } + + .nl1-ns { margin-left: -0.25rem; } + .nl2-ns { margin-left: -0.5rem; } + .nl3-ns { margin-left: -1rem; } + .nl4-ns { margin-left: -2rem; } + .nl5-ns { margin-left: -4rem; } + .nl6-ns { margin-left: -8rem; } + .nl7-ns { margin-left: -16rem; } + + .nr1-ns { margin-right: -0.25rem; } + .nr2-ns { margin-right: -0.5rem; } + .nr3-ns { margin-right: -1rem; } + .nr4-ns { margin-right: -2rem; } + .nr5-ns { margin-right: -4rem; } + .nr6-ns { margin-right: -8rem; } + .nr7-ns { margin-right: -16rem; } + + .nb1-ns { margin-bottom: -0.25rem; } + .nb2-ns { margin-bottom: -0.5rem; } + .nb3-ns { margin-bottom: -1rem; } + .nb4-ns { margin-bottom: -2rem; } + .nb5-ns { margin-bottom: -4rem; } + .nb6-ns { margin-bottom: -8rem; } + .nb7-ns { margin-bottom: -16rem; } + + .nt1-ns { margin-top: -0.25rem; } + .nt2-ns { margin-top: -0.5rem; } + .nt3-ns { margin-top: -1rem; } + .nt4-ns { margin-top: -2rem; } + .nt5-ns { margin-top: -4rem; } + .nt6-ns { margin-top: -8rem; } + .nt7-ns { margin-top: -16rem; } + +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .na1-m { margin: -0.25rem; } + .na2-m { margin: -0.5rem; } + .na3-m { margin: -1rem; } + .na4-m { margin: -2rem; } + .na5-m { margin: -4rem; } + .na6-m { margin: -8rem; } + .na7-m { margin: -16rem; } + + .nl1-m { margin-left: -0.25rem; } + .nl2-m { margin-left: -0.5rem; } + .nl3-m { margin-left: -1rem; } + .nl4-m { margin-left: -2rem; } + .nl5-m { margin-left: -4rem; } + .nl6-m { margin-left: -8rem; } + .nl7-m { margin-left: -16rem; } + + .nr1-m { margin-right: -0.25rem; } + .nr2-m { margin-right: -0.5rem; } + .nr3-m { margin-right: -1rem; } + .nr4-m { margin-right: -2rem; } + .nr5-m { margin-right: -4rem; } + .nr6-m { margin-right: -8rem; } + .nr7-m { margin-right: -16rem; } + + .nb1-m { margin-bottom: -0.25rem; } + .nb2-m { margin-bottom: -0.5rem; } + .nb3-m { margin-bottom: -1rem; } + .nb4-m { margin-bottom: -2rem; } + .nb5-m { margin-bottom: -4rem; } + .nb6-m { margin-bottom: -8rem; } + .nb7-m { margin-bottom: -16rem; } + + .nt1-m { margin-top: -0.25rem; } + .nt2-m { margin-top: -0.5rem; } + .nt3-m { margin-top: -1rem; } + .nt4-m { margin-top: -2rem; } + .nt5-m { margin-top: -4rem; } + .nt6-m { margin-top: -8rem; } + .nt7-m { margin-top: -16rem; } + +} + +@media screen and (min-width: 60em) { + .na1-l { margin: -0.25rem; } + .na2-l { margin: -0.5rem; } + .na3-l { margin: -1rem; } + .na4-l { margin: -2rem; } + .na5-l { margin: -4rem; } + .na6-l { margin: -8rem; } + .na7-l { margin: -16rem; } + + .nl1-l { margin-left: -0.25rem; } + .nl2-l { margin-left: -0.5rem; } + .nl3-l { margin-left: -1rem; } + .nl4-l { margin-left: -2rem; } + .nl5-l { margin-left: -4rem; } + .nl6-l { margin-left: -8rem; } + .nl7-l { margin-left: -16rem; } + + .nr1-l { margin-right: -0.25rem; } + .nr2-l { margin-right: -0.5rem; } + .nr3-l { margin-right: -1rem; } + .nr4-l { margin-right: -2rem; } + .nr5-l { margin-right: -4rem; } + .nr6-l { margin-right: -8rem; } + .nr7-l { margin-right: -16rem; } + + .nb1-l { margin-bottom: -0.25rem; } + .nb2-l { margin-bottom: -0.5rem; } + .nb3-l { margin-bottom: -1rem; } + .nb4-l { margin-bottom: -2rem; } + .nb5-l { margin-bottom: -4rem; } + .nb6-l { margin-bottom: -8rem; } + .nb7-l { margin-bottom: -16rem; } + + .nt1-l { margin-top: -0.25rem; } + .nt2-l { margin-top: -0.5rem; } + .nt3-l { margin-top: -1rem; } + .nt4-l { margin-top: -2rem; } + .nt5-l { margin-top: -4rem; } + .nt6-l { margin-top: -8rem; } + .nt7-l { margin-top: -16rem; } +} + +/* + + TABLES + Docs: http://tachyons.io/docs/elements/tables/ + +*/ + +.collapse { + border-collapse: collapse; + border-spacing: 0; +} + +.striped--light-silver:nth-child(odd) { + background-color: #aaa; +} + +.striped--moon-gray:nth-child(odd) { + background-color: #ccc; +} + +.striped--light-gray:nth-child(odd) { + background-color: #eee; +} + +.striped--near-white:nth-child(odd) { + background-color: #f4f4f4; +} + +.stripe-light:nth-child(odd) { + background-color: rgba(255, 255, 255, .1); +} + +.stripe-dark:nth-child(odd) { + background-color: rgba(0, 0, 0, .1); +} + +/* + + TEXT DECORATION + Docs: http://tachyons.io/docs/typography/text-decoration/ + + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.strike { text-decoration: line-through; } + +.underline { text-decoration: underline; } + +.no-underline { text-decoration: none; } + +@media screen and (min-width: 30em) { + .strike-ns { text-decoration: line-through; } + .underline-ns { text-decoration: underline; } + .no-underline-ns { text-decoration: none; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .strike-m { text-decoration: line-through; } + .underline-m { text-decoration: underline; } + .no-underline-m { text-decoration: none; } +} + +@media screen and (min-width: 60em) { + .strike-l { text-decoration: line-through; } + .underline-l { text-decoration: underline; } + .no-underline-l { text-decoration: none; } +} + +/* + + TEXT ALIGN + Docs: http://tachyons.io/docs/typography/text-align/ + + Base + t = text-align + + Modifiers + l = left + r = right + c = center + j = justify + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.tl { text-align: left; } + +.tr { text-align: right; } + +.tc { text-align: center; } + +.tj { text-align: justify; } + +@media screen and (min-width: 30em) { + .tl-ns { text-align: left; } + .tr-ns { text-align: right; } + .tc-ns { text-align: center; } + .tj-ns { text-align: justify; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .tl-m { text-align: left; } + .tr-m { text-align: right; } + .tc-m { text-align: center; } + .tj-m { text-align: justify; } +} + +@media screen and (min-width: 60em) { + .tl-l { text-align: left; } + .tr-l { text-align: right; } + .tc-l { text-align: center; } + .tj-l { text-align: justify; } +} + +/* + + TEXT TRANSFORM + Docs: http://tachyons.io/docs/typography/text-transform/ + + Base: + tt = text-transform + + Modifiers + c = capitalize + l = lowercase + u = uppercase + n = none + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.ttc { text-transform: capitalize; } + +.ttl { text-transform: lowercase; } + +.ttu { text-transform: uppercase; } + +.ttn { text-transform: none; } + +@media screen and (min-width: 30em) { + .ttc-ns { text-transform: capitalize; } + .ttl-ns { text-transform: lowercase; } + .ttu-ns { text-transform: uppercase; } + .ttn-ns { text-transform: none; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .ttc-m { text-transform: capitalize; } + .ttl-m { text-transform: lowercase; } + .ttu-m { text-transform: uppercase; } + .ttn-m { text-transform: none; } +} + +@media screen and (min-width: 60em) { + .ttc-l { text-transform: capitalize; } + .ttl-l { text-transform: lowercase; } + .ttu-l { text-transform: uppercase; } + .ttn-l { text-transform: none; } +} + +/* + + TYPE SCALE + Docs: http://tachyons.io/docs/typography/scale/ + + Base: + f = font-size + + Modifiers + 1 = 1st step in size scale + 2 = 2nd step in size scale + 3 = 3rd step in size scale + 4 = 4th step in size scale + 5 = 5th step in size scale + 6 = 6th step in size scale + 7 = 7th step in size scale + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large +*/ + +/* + * For Hero/Marketing Titles + * + * These generally are too large for mobile + * so be careful using them on smaller screens. + * */ + +.f-6, +.f-headline { + font-size: 6rem; +} + +.f-5, +.f-subheadline { + font-size: 5rem; +} + +/* Type Scale */ + +.f1 { font-size: 3rem; } + +.f2 { font-size: 2.25rem; } + +.f3 { font-size: 1.5rem; } + +.f4 { font-size: 1.25rem; } + +.f5 { font-size: 1rem; } + +.f6 { font-size: .875rem; } + +.f7 { font-size: .75rem; } + +/* Small and hard to read for many people so use with extreme caution */ + +@media screen and (min-width: 30em){ + .f-6-ns, + .f-headline-ns { font-size: 6rem; } + .f-5-ns, + .f-subheadline-ns { font-size: 5rem; } + .f1-ns { font-size: 3rem; } + .f2-ns { font-size: 2.25rem; } + .f3-ns { font-size: 1.5rem; } + .f4-ns { font-size: 1.25rem; } + .f5-ns { font-size: 1rem; } + .f6-ns { font-size: .875rem; } + .f7-ns { font-size: .75rem; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .f-6-m, + .f-headline-m { font-size: 6rem; } + .f-5-m, + .f-subheadline-m { font-size: 5rem; } + .f1-m { font-size: 3rem; } + .f2-m { font-size: 2.25rem; } + .f3-m { font-size: 1.5rem; } + .f4-m { font-size: 1.25rem; } + .f5-m { font-size: 1rem; } + .f6-m { font-size: .875rem; } + .f7-m { font-size: .75rem; } +} + +@media screen and (min-width: 60em) { + .f-6-l, + .f-headline-l { + font-size: 6rem; + } + .f-5-l, + .f-subheadline-l { + font-size: 5rem; + } + .f1-l { font-size: 3rem; } + .f2-l { font-size: 2.25rem; } + .f3-l { font-size: 1.5rem; } + .f4-l { font-size: 1.25rem; } + .f5-l { font-size: 1rem; } + .f6-l { font-size: .875rem; } + .f7-l { font-size: .75rem; } +} + +/* + + TYPOGRAPHY + http://tachyons.io/docs/typography/measure/ + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +/* Measure is limited to ~66 characters */ + +.measure { + max-width: 30em; +} + +/* Measure is limited to ~80 characters */ + +.measure-wide { + max-width: 34em; +} + +/* Measure is limited to ~45 characters */ + +.measure-narrow { + max-width: 20em; +} + +/* Book paragraph style - paragraphs are indented with no vertical spacing. */ + +.indent { + text-indent: 1em; + margin-top: 0; + margin-bottom: 0; +} + +.small-caps { + -webkit-font-feature-settings: "c2sc"; + font-feature-settings: "c2sc"; + font-variant: small-caps; +} + +/* Combine this class with a width to truncate text (or just leave as is to truncate at width of containing element. */ + +.truncate { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +@media screen and (min-width: 30em) { + .measure-ns { + max-width: 30em; + } + .measure-wide-ns { + max-width: 34em; + } + .measure-narrow-ns { + max-width: 20em; + } + .indent-ns { + text-indent: 1em; + margin-top: 0; + margin-bottom: 0; + } + .small-caps-ns { + -webkit-font-feature-settings: "c2sc"; + font-feature-settings: "c2sc"; + font-variant: small-caps; + } + .truncate-ns { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .measure-m { + max-width: 30em; + } + .measure-wide-m { + max-width: 34em; + } + .measure-narrow-m { + max-width: 20em; + } + .indent-m { + text-indent: 1em; + margin-top: 0; + margin-bottom: 0; + } + .small-caps-m { + -webkit-font-feature-settings: "c2sc"; + font-feature-settings: "c2sc"; + font-variant: small-caps; + } + .truncate-m { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +} + +@media screen and (min-width: 60em) { + .measure-l { + max-width: 30em; + } + .measure-wide-l { + max-width: 34em; + } + .measure-narrow-l { + max-width: 20em; + } + .indent-l { + text-indent: 1em; + margin-top: 0; + margin-bottom: 0; + } + .small-caps-l { + -webkit-font-feature-settings: "c2sc"; + font-feature-settings: "c2sc"; + font-variant: small-caps; + } + .truncate-l { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +} + +/* + + UTILITIES + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +/* Equivalent to .overflow-y-scroll */ + +.overflow-container { + overflow-y: scroll; +} + +.center { + margin-right: auto; + margin-left: auto; +} + +.mr-auto { margin-right: auto; } + +.ml-auto { margin-left: auto; } + +@media screen and (min-width: 30em){ + .center-ns { + margin-right: auto; + margin-left: auto; + } + .mr-auto-ns { margin-right: auto; } + .ml-auto-ns { margin-left: auto; } +} + +@media screen and (min-width: 30em) and (max-width: 60em){ + .center-m { + margin-right: auto; + margin-left: auto; + } + .mr-auto-m { margin-right: auto; } + .ml-auto-m { margin-left: auto; } +} + +@media screen and (min-width: 60em){ + .center-l { + margin-right: auto; + margin-left: auto; + } + .mr-auto-l { margin-right: auto; } + .ml-auto-l { margin-left: auto; } +} + +/* + + VISIBILITY + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +/* + Text that is hidden but accessible + Ref: http://snook.ca/archives/html_and_css/hiding-content-for-accessibility +*/ + +.clip { + position: fixed !important; + _position: absolute !important; + clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ + clip: rect(1px, 1px, 1px, 1px); +} + +@media screen and (min-width: 30em) { + .clip-ns { + position: fixed !important; + _position: absolute !important; + clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ + clip: rect(1px, 1px, 1px, 1px); + } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .clip-m { + position: fixed !important; + _position: absolute !important; + clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ + clip: rect(1px, 1px, 1px, 1px); + } +} + +@media screen and (min-width: 60em) { + .clip-l { + position: fixed !important; + _position: absolute !important; + clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ + clip: rect(1px, 1px, 1px, 1px); + } +} + +/* + + WHITE SPACE + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.ws-normal { white-space: normal; } + +.nowrap { white-space: nowrap; } + +.pre { white-space: pre; } + +@media screen and (min-width: 30em) { + .ws-normal-ns { white-space: normal; } + .nowrap-ns { white-space: nowrap; } + .pre-ns { white-space: pre; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .ws-normal-m { white-space: normal; } + .nowrap-m { white-space: nowrap; } + .pre-m { white-space: pre; } +} + +@media screen and (min-width: 60em) { + .ws-normal-l { white-space: normal; } + .nowrap-l { white-space: nowrap; } + .pre-l { white-space: pre; } +} + +/* + + VERTICAL ALIGN + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.v-base { vertical-align: baseline; } + +.v-mid { vertical-align: middle; } + +.v-top { vertical-align: top; } + +.v-btm { vertical-align: bottom; } + +@media screen and (min-width: 30em) { + .v-base-ns { vertical-align: baseline; } + .v-mid-ns { vertical-align: middle; } + .v-top-ns { vertical-align: top; } + .v-btm-ns { vertical-align: bottom; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .v-base-m { vertical-align: baseline; } + .v-mid-m { vertical-align: middle; } + .v-top-m { vertical-align: top; } + .v-btm-m { vertical-align: bottom; } +} + +@media screen and (min-width: 60em) { + .v-base-l { vertical-align: baseline; } + .v-mid-l { vertical-align: middle; } + .v-top-l { vertical-align: top; } + .v-btm-l { vertical-align: bottom; } +} + +/* + + HOVER EFFECTS + Docs: http://tachyons.io/docs/themes/hovers/ + + - Dim + - Glow + - Hide Child + - Underline text + - Grow + - Pointer + - Shadow + +*/ + +/* + + Dim element on hover by adding the dim class. + +*/ + +.dim { + opacity: 1; + transition: opacity .15s ease-in; +} + +.dim:hover, +.dim:focus { + opacity: .5; + transition: opacity .15s ease-in; +} + +.dim:active { + opacity: .8; transition: opacity .15s ease-out; +} + +/* + + Animate opacity to 100% on hover by adding the glow class. + +*/ + +.glow { + transition: opacity .15s ease-in; +} + +.glow:hover, +.glow:focus { + opacity: 1; + transition: opacity .15s ease-in; +} + +/* + + Hide child & reveal on hover: + + Put the hide-child class on a parent element and any nested element with the + child class will be hidden and displayed on hover or focus. + +
+
Hidden until hover or focus
+
Hidden until hover or focus
+
Hidden until hover or focus
+
Hidden until hover or focus
+
+*/ + +.hide-child .child { + opacity: 0; + transition: opacity .15s ease-in; +} + +.hide-child:hover .child, +.hide-child:focus .child, +.hide-child:active .child { + opacity: 1; + transition: opacity .15s ease-in; +} + +.underline-hover:hover, +.underline-hover:focus { + text-decoration: underline; +} + +/* Can combine this with overflow-hidden to make background images grow on hover + * even if you are using background-size: cover */ + +.grow { + -moz-osx-font-smoothing: grayscale; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-transform: translateZ(0); + transform: translateZ(0); + transition: -webkit-transform 0.25s ease-out; + transition: transform 0.25s ease-out; + transition: transform 0.25s ease-out, -webkit-transform 0.25s ease-out; +} + +.grow:hover, +.grow:focus { + -webkit-transform: scale(1.05); + transform: scale(1.05); +} + +.grow:active { + -webkit-transform: scale(.90); + transform: scale(.90); +} + +.grow-large { + -moz-osx-font-smoothing: grayscale; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-transform: translateZ(0); + transform: translateZ(0); + transition: -webkit-transform .25s ease-in-out; + transition: transform .25s ease-in-out; + transition: transform .25s ease-in-out, -webkit-transform .25s ease-in-out; +} + +.grow-large:hover, +.grow-large:focus { + -webkit-transform: scale(1.2); + transform: scale(1.2); +} + +.grow-large:active { + -webkit-transform: scale(.95); + transform: scale(.95); +} + +/* Add pointer on hover */ + +.pointer:hover { + cursor: pointer; +} + +/* + Add shadow on hover. + + Performant box-shadow animation pattern from + http://tobiasahlin.com/blog/how-to-animate-box-shadow/ +*/ + +.shadow-hover { + cursor: pointer; + position: relative; + transition: all 0.5s cubic-bezier(0.165, 0.84, 0.44, 1); +} + +.shadow-hover::after { + content: ''; + box-shadow: 0px 0px 16px 2px rgba(0, 0, 0, .2); + border-radius: inherit; + opacity: 0; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: -1; + transition: opacity 0.5s cubic-bezier(0.165, 0.84, 0.44, 1); +} + +.shadow-hover:hover::after, +.shadow-hover:focus::after { + opacity: 1; +} + +/* Combine with classes in skins and skins-pseudo for + * many different transition possibilities. */ + +.bg-animate, +.bg-animate:hover, +.bg-animate:focus { + transition: background-color .15s ease-in-out; +} + +/* + + Z-INDEX + + Base + z = z-index + + Modifiers + -0 = literal value 0 + -1 = literal value 1 + -2 = literal value 2 + -3 = literal value 3 + -4 = literal value 4 + -5 = literal value 5 + -999 = literal value 999 + -9999 = literal value 9999 + + -max = largest accepted z-index value as integer + + -inherit = string value inherit + -initial = string value initial + -unset = string value unset + + MDN: https://developer.mozilla.org/en/docs/Web/CSS/z-index + Spec: http://www.w3.org/TR/CSS2/zindex.html + Articles: + https://philipwalton.com/articles/what-no-one-told-you-about-z-index/ + + Tips on extending: + There might be a time worth using negative z-index values. + Or if you are using tachyons with another project, you might need to + adjust these values to suit your needs. + +*/ + +.z-0 { z-index: 0; } + +.z-1 { z-index: 1; } + +.z-2 { z-index: 2; } + +.z-3 { z-index: 3; } + +.z-4 { z-index: 4; } + +.z-5 { z-index: 5; } + +.z-999 { z-index: 999; } + +.z-9999 { z-index: 9999; } + +.z-max { + z-index: 2147483647; +} + +.z-inherit { z-index: inherit; } + +.z-initial { z-index: auto; z-index: initial; } + +.z-unset { z-index: unset; } + +/* + + NESTED + Tachyons module for styling nested elements + that are generated by a cms. + +*/ + +.nested-copy-line-height p, +.nested-copy-line-height ul, +.nested-copy-line-height ol { + line-height: 1.5; +} + +.nested-headline-line-height h1, +.nested-headline-line-height h2, +.nested-headline-line-height h3, +.nested-headline-line-height h4, +.nested-headline-line-height h5, +.nested-headline-line-height h6 { + line-height: 1.25; +} + +.nested-list-reset ul, +.nested-list-reset ol { + padding-left: 0; + margin-left: 0; + list-style-type: none; +} + +.nested-copy-indent p+p { + text-indent: 1em; + margin-top: 0; + margin-bottom: 0; +} + +.nested-copy-separator p+p { + margin-top: 1.5em; +} + +.nested-img img { + width: 100%; + max-width: 100%; + display: block; +} + +.nested-links a { + color: #357edd; + transition: color .15s ease-in; +} + +.nested-links a:hover, +.nested-links a:focus { + color: #96ccff; + transition: color .15s ease-in; +} + +/* + + STYLES + + Add custom styles here. + +*/ + +/* Variables */ + +/* Importing here will allow you to override any variables in the modules */ + +/* + + Tachyons + COLOR VARIABLES + + Grayscale + - Solids + - Transparencies + Colors + +*/ + +/* + + CUSTOM MEDIA QUERIES + + Media query values can be changed to fit your own content. + There are no magic bullets when it comes to media query width values. + They should be declared in em units - and they should be set to meet + the needs of your content. You can also add additional media queries, + or remove some of the existing ones. + + These media queries can be referenced like so: + + @media (--breakpoint-not-small) { + .medium-and-larger-specific-style { + background-color: red; + } + } + + @media (--breakpoint-medium) { + .medium-screen-specific-style { + background-color: red; + } + } + + @media (--breakpoint-large) { + .large-and-larger-screen-specific-style { + background-color: red; + } + } + +*/ + +/* Media Queries */ + +/* Debugging */ + +/* @import 'tachyons/src/_debug-children'; +@import 'tachyons/src/_debug-grid'; */ + +/* Uncomment out the line below to help debug layout issues */ + +/* @import 'tachyons/src/_debug'; */ + +pre, .pre { + overflow-x: auto; + overflow-y: hidden; + overflow: scroll; +} + +pre code { + display: block; + padding: 1.5em 1.5em; + white-space: pre; + font-size: .875rem; + line-height: 2; + +} + +pre { + background-color: #222; + color: #ddd; + white-space: pre; + + -webkit-hyphens: none; + + -ms-hyphens: none; + + hyphens: none; + position: relative; +} + +/* pagination.html: https://github.com/spf13/hugo/blob/master/tpl/tplimpl/template_embedded.go#L117 */ + +.pagination { + margin: 3rem 0; +} + +.pagination li { + display: inline-block; + margin-right: .375rem; + font-size: .875rem; + margin-bottom: 2.5em; +} + +.pagination li a { + padding: .5rem .625rem; + background-color: white; + color: #333; + border: 1px solid #ddd; + border-radius: 3px; + text-decoration: none; +} + +.pagination li.disabled { + display: none; +} + +.pagination li.active a:link, +.pagination li.active a:active, +.pagination li.active a:visited { + background-color: #ddd; +} + +#TableOfContents ul li { + margin-bottom: 1em; +} + +.facebook, .twitter, .instagram, .youtube, .github, .gitlab, .keybase, .linkedin, .medium, .mastodon, .slack, .stackoverflow, .rss { + fill: #BABABA; +} + +.new-window { + opacity: 0; + display: inline-block; + vertical-align: top; +} + +.link-transition:hover .new-window{ + opacity: 1; +} + +.facebook:hover { + fill: #3b5998; +} + +.twitter:hover { + fill: #1da1f2; +} + +.instagram:hover { + fill: #e1306c; +} + +.youtube:hover { + fill: #cd201f; +} + +.github:hover { + fill: #6cc644; +} + +.gitlab:hover { + fill: #FC6D26; +} + +.keybase:hover { + fill: #3d76ff; +} + +.linkedin:hover { + fill: #0077b5 +} + +.medium:hover { + fill: #0077b5 +} + +.mastodon:hover { + fill: #3088d4; +} + +.slack:hover { + fill: #E01E5A; +} + +.stackoverflow:hover { + fill: #f48024; +} + +.rss:hover{ + fill: #ff6f1a; +} + +/* Put your custom styles here and run `npm start` from the "src" directory on */ + +#TableOfContents ul li { + margin-bottom: 1em; +} + +.lh-copy blockquote { + display: block; + font-size: .875em; + margin-left: 2rem; + margin-top: 2rem; + margin-bottom: 2rem; + border-left: 4px solid #ccc; + padding-left: 1rem; + +} + +.nested-links a{ + word-wrap: break-word; +} diff --git a/public/dist/css/app.7e7787cc1402d7de28bc90f7e65adf96.css b/public/dist/css/app.7e7787cc1402d7de28bc90f7e65adf96.css new file mode 100644 index 00000000..c6b3c06e --- /dev/null +++ b/public/dist/css/app.7e7787cc1402d7de28bc90f7e65adf96.css @@ -0,0 +1,5872 @@ +/*! TACHYONS v4.9.1 | http://tachyons.io */ + +/* + * + * ________ ______ + * ___ __/_____ _________ /______ ______________________ + * __ / _ __ `/ ___/_ __ \_ / / / __ \_ __ \_ ___/ + * _ / / /_/ // /__ _ / / / /_/ // /_/ / / / /(__ ) + * /_/ \__,_/ \___/ /_/ /_/_\__, / \____//_/ /_//____/ + * /____/ + * + * TABLE OF CONTENTS + * + * 1. External Library Includes + * - Normalize.css | http://normalize.css.github.io + * 2. Tachyons Modules + * 3. Variables + * - Media Queries + * - Colors + * 4. Debugging + * - Debug all + * - Debug children + * + */ + +/* External Library Includes */ + +/*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */ + +/* Document + ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in iOS. + */ + +html { + line-height: 1.15; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/* Sections + ========================================================================== */ + +/** + * Remove the margin in all browsers. + */ + +body { + margin: 0; +} + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/* Grouping content + ========================================================================== */ + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + +hr { + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +pre { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Remove the gray background on active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * 1. Remove the bottom border in Chrome 57- + * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. + */ + +abbr[title] { + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + text-decoration: underline dotted; /* 2 */ +} + +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + +b, +strong { + font-weight: bolder; +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +code, +kbd, +samp { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/** + * Add the correct font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` elements from affecting the line height in + * all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove the border on images inside links in IE 10. + */ + +img { + border-style: none; +} + +/* Forms + ========================================================================== */ + +/** + * 1. Change the font styles in all browsers. + * 2. Remove the margin in Firefox and Safari. + */ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ +} + +/** + * Show the overflow in IE. + * 1. Show the overflow in Edge. + */ + +button, +input { /* 1 */ + overflow: visible; +} + +/** + * Remove the inheritance of text transform in Edge, Firefox, and IE. + * 1. Remove the inheritance of text transform in Firefox. + */ + +button, +select { /* 1 */ + text-transform: none; +} + +/** + * Correct the inability to style clickable types in iOS and Safari. + */ + +button, +[type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} + +/** + * Remove the inner border and padding in Firefox. + */ + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus styles unset by the previous rule. + */ + +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; +} + +/** + * Correct the padding in Firefox. + */ + +fieldset { + padding: 0.35em 0.75em 0.625em; +} + +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + +legend { + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ +} + +/** + * Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + +progress { + vertical-align: baseline; +} + +/** + * Remove the default vertical scrollbar in IE 10+. + */ + +textarea { + overflow: auto; +} + +/** + * 1. Add the correct box sizing in IE 10. + * 2. Remove the padding in IE 10. + */ + +[type="checkbox"], +[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type="search"] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Remove the inner padding in Chrome and Safari on macOS. + */ + +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + +::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} + +/* Interactive + ========================================================================== */ + +/* + * Add the correct display in Edge, IE 10+, and Firefox. + */ + +details { + display: block; +} + +/* + * Add the correct display in all browsers. + */ + +summary { + display: list-item; +} + +/* Misc + ========================================================================== */ + +/** + * Add the correct display in IE 10+. + */ + +template { + display: none; +} + +/** + * Add the correct display in IE 10. + */ + +[hidden] { + display: none; +} + +/* Modules */ + +/* + + BOX SIZING + +*/ + +html, +body, +div, +article, +aside, +section, +main, +nav, +footer, +header, +form, +fieldset, +legend, +pre, +code, +a, +h1,h2,h3,h4,h5,h6, +p, +ul, +ol, +li, +dl, +dt, +dd, +blockquote, +figcaption, +figure, +textarea, +table, +td, +th, +tr, +input[type="email"], +input[type="number"], +input[type="password"], +input[type="tel"], +input[type="text"], +input[type="url"], +.border-box { + box-sizing: border-box; +} + +/* + + ASPECT RATIOS + +*/ + +/* This is for fluid media that is embedded from third party sites like youtube, vimeo etc. + * Wrap the outer element in aspect-ratio and then extend it with the desired ratio i.e + * Make sure there are no height and width attributes on the embedded media. + * Adapted from: https://github.com/suitcss/components-flex-embed + * + * Example: + * + *
+ * + *
+ * + * */ + +.aspect-ratio { + height: 0; + position: relative; +} + +.aspect-ratio--16x9 { padding-bottom: 56.25%; } + +.aspect-ratio--9x16 { padding-bottom: 177.77%; } + +.aspect-ratio--4x3 { padding-bottom: 75%; } + +.aspect-ratio--3x4 { padding-bottom: 133.33%; } + +.aspect-ratio--6x4 { padding-bottom: 66.6%; } + +.aspect-ratio--4x6 { padding-bottom: 150%; } + +.aspect-ratio--8x5 { padding-bottom: 62.5%; } + +.aspect-ratio--5x8 { padding-bottom: 160%; } + +.aspect-ratio--7x5 { padding-bottom: 71.42%; } + +.aspect-ratio--5x7 { padding-bottom: 140%; } + +.aspect-ratio--1x1 { padding-bottom: 100%; } + +.aspect-ratio--object { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100; +} + +@media screen and (min-width: 30em){ + .aspect-ratio-ns { + height: 0; + position: relative; + } + .aspect-ratio--16x9-ns { padding-bottom: 56.25%; } + .aspect-ratio--9x16-ns { padding-bottom: 177.77%; } + .aspect-ratio--4x3-ns { padding-bottom: 75%; } + .aspect-ratio--3x4-ns { padding-bottom: 133.33%; } + .aspect-ratio--6x4-ns { padding-bottom: 66.6%; } + .aspect-ratio--4x6-ns { padding-bottom: 150%; } + .aspect-ratio--8x5-ns { padding-bottom: 62.5%; } + .aspect-ratio--5x8-ns { padding-bottom: 160%; } + .aspect-ratio--7x5-ns { padding-bottom: 71.42%; } + .aspect-ratio--5x7-ns { padding-bottom: 140%; } + .aspect-ratio--1x1-ns { padding-bottom: 100%; } + .aspect-ratio--object-ns { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100; + } +} + +@media screen and (min-width: 30em) and (max-width: 60em){ + .aspect-ratio-m { + height: 0; + position: relative; + } + .aspect-ratio--16x9-m { padding-bottom: 56.25%; } + .aspect-ratio--9x16-m { padding-bottom: 177.77%; } + .aspect-ratio--4x3-m { padding-bottom: 75%; } + .aspect-ratio--3x4-m { padding-bottom: 133.33%; } + .aspect-ratio--6x4-m { padding-bottom: 66.6%; } + .aspect-ratio--4x6-m { padding-bottom: 150%; } + .aspect-ratio--8x5-m { padding-bottom: 62.5%; } + .aspect-ratio--5x8-m { padding-bottom: 160%; } + .aspect-ratio--7x5-m { padding-bottom: 71.42%; } + .aspect-ratio--5x7-m { padding-bottom: 140%; } + .aspect-ratio--1x1-m { padding-bottom: 100%; } + .aspect-ratio--object-m { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100; + } +} + +@media screen and (min-width: 60em){ + .aspect-ratio-l { + height: 0; + position: relative; + } + .aspect-ratio--16x9-l { padding-bottom: 56.25%; } + .aspect-ratio--9x16-l { padding-bottom: 177.77%; } + .aspect-ratio--4x3-l { padding-bottom: 75%; } + .aspect-ratio--3x4-l { padding-bottom: 133.33%; } + .aspect-ratio--6x4-l { padding-bottom: 66.6%; } + .aspect-ratio--4x6-l { padding-bottom: 150%; } + .aspect-ratio--8x5-l { padding-bottom: 62.5%; } + .aspect-ratio--5x8-l { padding-bottom: 160%; } + .aspect-ratio--7x5-l { padding-bottom: 71.42%; } + .aspect-ratio--5x7-l { padding-bottom: 140%; } + .aspect-ratio--1x1-l { padding-bottom: 100%; } + .aspect-ratio--object-l { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100; + } +} + +/* + + IMAGES + Docs: http://tachyons.io/docs/elements/images/ + +*/ + +/* Responsive images! */ + +img { max-width: 100%; } + +/* + + BACKGROUND SIZE + Docs: http://tachyons.io/docs/themes/background-size/ + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +/* + Often used in combination with background image set as an inline style + on an html element. +*/ + +.cover { background-size: cover!important; } + +.contain { background-size: contain!important; } + +@media screen and (min-width: 30em) { + .cover-ns { background-size: cover!important; } + .contain-ns { background-size: contain!important; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .cover-m { background-size: cover!important; } + .contain-m { background-size: contain!important; } +} + +@media screen and (min-width: 60em) { + .cover-l { background-size: cover!important; } + .contain-l { background-size: contain!important; } +} + +/* + + BACKGROUND POSITION + + Base: + bg = background + + Modifiers: + -center = center center + -top = top center + -right = center right + -bottom = bottom center + -left = center left + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + + */ + +.bg-center { + background-repeat: no-repeat; + background-position: center center; +} + +.bg-top { + background-repeat: no-repeat; + background-position: top center; +} + +.bg-right { + background-repeat: no-repeat; + background-position: center right; +} + +.bg-bottom { + background-repeat: no-repeat; + background-position: bottom center; +} + +.bg-left { + background-repeat: no-repeat; + background-position: center left; +} + +@media screen and (min-width: 30em) { + .bg-center-ns { + background-repeat: no-repeat; + background-position: center center; + } + + .bg-top-ns { + background-repeat: no-repeat; + background-position: top center; + } + + .bg-right-ns { + background-repeat: no-repeat; + background-position: center right; + } + + .bg-bottom-ns { + background-repeat: no-repeat; + background-position: bottom center; + } + + .bg-left-ns { + background-repeat: no-repeat; + background-position: center left; + } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .bg-center-m { + background-repeat: no-repeat; + background-position: center center; + } + + .bg-top-m { + background-repeat: no-repeat; + background-position: top center; + } + + .bg-right-m { + background-repeat: no-repeat; + background-position: center right; + } + + .bg-bottom-m { + background-repeat: no-repeat; + background-position: bottom center; + } + + .bg-left-m { + background-repeat: no-repeat; + background-position: center left; + } +} + +@media screen and (min-width: 60em) { + .bg-center-l { + background-repeat: no-repeat; + background-position: center center; + } + + .bg-top-l { + background-repeat: no-repeat; + background-position: top center; + } + + .bg-right-l { + background-repeat: no-repeat; + background-position: center right; + } + + .bg-bottom-l { + background-repeat: no-repeat; + background-position: bottom center; + } + + .bg-left-l { + background-repeat: no-repeat; + background-position: center left; + } +} + +/* + + OUTLINES + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.outline { outline: 1px solid; } + +.outline-transparent { outline: 1px solid transparent; } + +.outline-0 { outline: 0; } + +@media screen and (min-width: 30em) { + .outline-ns { outline: 1px solid; } + .outline-transparent-ns { outline: 1px solid transparent; } + .outline-0-ns { outline: 0; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .outline-m { outline: 1px solid; } + .outline-transparent-m { outline: 1px solid transparent; } + .outline-0-m { outline: 0; } +} + +@media screen and (min-width: 60em) { + .outline-l { outline: 1px solid; } + .outline-transparent-l { outline: 1px solid transparent; } + .outline-0-l { outline: 0; } +} + +/* + + BORDERS + Docs: http://tachyons.io/docs/themes/borders/ + + Base: + b = border + + Modifiers: + a = all + t = top + r = right + b = bottom + l = left + n = none + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.ba { border-style: solid; border-width: 1px; } + +.bt { border-top-style: solid; border-top-width: 1px; } + +.br { border-right-style: solid; border-right-width: 1px; } + +.bb { border-bottom-style: solid; border-bottom-width: 1px; } + +.bl { border-left-style: solid; border-left-width: 1px; } + +.bn { border-style: none; border-width: 0; } + +@media screen and (min-width: 30em) { + .ba-ns { border-style: solid; border-width: 1px; } + .bt-ns { border-top-style: solid; border-top-width: 1px; } + .br-ns { border-right-style: solid; border-right-width: 1px; } + .bb-ns { border-bottom-style: solid; border-bottom-width: 1px; } + .bl-ns { border-left-style: solid; border-left-width: 1px; } + .bn-ns { border-style: none; border-width: 0; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .ba-m { border-style: solid; border-width: 1px; } + .bt-m { border-top-style: solid; border-top-width: 1px; } + .br-m { border-right-style: solid; border-right-width: 1px; } + .bb-m { border-bottom-style: solid; border-bottom-width: 1px; } + .bl-m { border-left-style: solid; border-left-width: 1px; } + .bn-m { border-style: none; border-width: 0; } +} + +@media screen and (min-width: 60em) { + .ba-l { border-style: solid; border-width: 1px; } + .bt-l { border-top-style: solid; border-top-width: 1px; } + .br-l { border-right-style: solid; border-right-width: 1px; } + .bb-l { border-bottom-style: solid; border-bottom-width: 1px; } + .bl-l { border-left-style: solid; border-left-width: 1px; } + .bn-l { border-style: none; border-width: 0; } +} + +/* + + BORDER COLORS + Docs: http://tachyons.io/docs/themes/borders/ + + Border colors can be used to extend the base + border classes ba,bt,bb,br,bl found in the _borders.css file. + + The base border class by default will set the color of the border + to that of the current text color. These classes are for the cases + where you desire for the text and border colors to be different. + + Base: + b = border + + Modifiers: + --color-name = each color variable name is also a border color name + +*/ + +.b--black { border-color: #000; } + +.b--near-black { border-color: #111; } + +.b--dark-gray { border-color: #333; } + +.b--mid-gray { border-color: #555; } + +.b--gray { border-color: #777; } + +.b--silver { border-color: #999; } + +.b--light-silver { border-color: #aaa; } + +.b--moon-gray { border-color: #ccc; } + +.b--light-gray { border-color: #eee; } + +.b--near-white { border-color: #f4f4f4; } + +.b--white { border-color: #fff; } + +.b--white-90 { border-color: rgba(255, 255, 255, .9); } + +.b--white-80 { border-color: rgba(255, 255, 255, .8); } + +.b--white-70 { border-color: rgba(255, 255, 255, .7); } + +.b--white-60 { border-color: rgba(255, 255, 255, .6); } + +.b--white-50 { border-color: rgba(255, 255, 255, .5); } + +.b--white-40 { border-color: rgba(255, 255, 255, .4); } + +.b--white-30 { border-color: rgba(255, 255, 255, .3); } + +.b--white-20 { border-color: rgba(255, 255, 255, .2); } + +.b--white-10 { border-color: rgba(255, 255, 255, .1); } + +.b--white-05 { border-color: rgba(255, 255, 255, .05); } + +.b--white-025 { border-color: rgba(255, 255, 255, .025); } + +.b--white-0125 { border-color: rgba(255, 255, 255, .0125); } + +.b--black-90 { border-color: rgba(0, 0, 0, .9); } + +.b--black-80 { border-color: rgba(0, 0, 0, .8); } + +.b--black-70 { border-color: rgba(0, 0, 0, .7); } + +.b--black-60 { border-color: rgba(0, 0, 0, .6); } + +.b--black-50 { border-color: rgba(0, 0, 0, .5); } + +.b--black-40 { border-color: rgba(0, 0, 0, .4); } + +.b--black-30 { border-color: rgba(0, 0, 0, .3); } + +.b--black-20 { border-color: rgba(0, 0, 0, .2); } + +.b--black-10 { border-color: rgba(0, 0, 0, .1); } + +.b--black-05 { border-color: rgba(0, 0, 0, .05); } + +.b--black-025 { border-color: rgba(0, 0, 0, .025); } + +.b--black-0125 { border-color: rgba(0, 0, 0, .0125); } + +.b--dark-red { border-color: #e7040f; } + +.b--red { border-color: #ff4136; } + +.b--light-red { border-color: #ff725c; } + +.b--orange { border-color: #ff6300; } + +.b--gold { border-color: #ffb700; } + +.b--yellow { border-color: #ffd700; } + +.b--light-yellow { border-color: #fbf1a9; } + +.b--purple { border-color: #5e2ca5; } + +.b--light-purple { border-color: #a463f2; } + +.b--dark-pink { border-color: #d5008f; } + +.b--hot-pink { border-color: #ff41b4; } + +.b--pink { border-color: #ff80cc; } + +.b--light-pink { border-color: #ffa3d7; } + +.b--dark-green { border-color: #137752; } + +.b--green { border-color: #19a974; } + +.b--light-green { border-color: #9eebcf; } + +.b--navy { border-color: #001b44; } + +.b--dark-blue { border-color: #00449e; } + +.b--blue { border-color: #357edd; } + +.b--light-blue { border-color: #96ccff; } + +.b--lightest-blue { border-color: #cdecff; } + +.b--washed-blue { border-color: #f6fffe; } + +.b--washed-green { border-color: #e8fdf5; } + +.b--washed-yellow { border-color: #fffceb; } + +.b--washed-red { border-color: #ffdfdf; } + +.b--transparent { border-color: transparent; } + +.b--inherit { border-color: inherit; } + +/* + + BORDER RADIUS + Docs: http://tachyons.io/docs/themes/border-radius/ + + Base: + br = border-radius + + Modifiers: + 0 = 0/none + 1 = 1st step in scale + 2 = 2nd step in scale + 3 = 3rd step in scale + 4 = 4th step in scale + + Literal values: + -100 = 100% + -pill = 9999px + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.br0 { border-radius: 0; } + +.br1 { border-radius: .125rem; } + +.br2 { border-radius: .25rem; } + +.br3 { border-radius: .5rem; } + +.br4 { border-radius: 1rem; } + +.br-100 { border-radius: 100%; } + +.br-pill { border-radius: 9999px; } + +.br--bottom { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + +.br--top { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + +.br--right { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + +.br--left { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + +@media screen and (min-width: 30em) { + .br0-ns { border-radius: 0; } + .br1-ns { border-radius: .125rem; } + .br2-ns { border-radius: .25rem; } + .br3-ns { border-radius: .5rem; } + .br4-ns { border-radius: 1rem; } + .br-100-ns { border-radius: 100%; } + .br-pill-ns { border-radius: 9999px; } + .br--bottom-ns { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + .br--top-ns { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + .br--right-ns { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .br--left-ns { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .br0-m { border-radius: 0; } + .br1-m { border-radius: .125rem; } + .br2-m { border-radius: .25rem; } + .br3-m { border-radius: .5rem; } + .br4-m { border-radius: 1rem; } + .br-100-m { border-radius: 100%; } + .br-pill-m { border-radius: 9999px; } + .br--bottom-m { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + .br--top-m { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + .br--right-m { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .br--left-m { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } +} + +@media screen and (min-width: 60em) { + .br0-l { border-radius: 0; } + .br1-l { border-radius: .125rem; } + .br2-l { border-radius: .25rem; } + .br3-l { border-radius: .5rem; } + .br4-l { border-radius: 1rem; } + .br-100-l { border-radius: 100%; } + .br-pill-l { border-radius: 9999px; } + .br--bottom-l { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + .br--top-l { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + .br--right-l { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .br--left-l { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } +} + +/* + + BORDER STYLES + Docs: http://tachyons.io/docs/themes/borders/ + + Depends on base border module in _borders.css + + Base: + b = border-style + + Modifiers: + --none = none + --dotted = dotted + --dashed = dashed + --solid = solid + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + + */ + +.b--dotted { border-style: dotted; } + +.b--dashed { border-style: dashed; } + +.b--solid { border-style: solid; } + +.b--none { border-style: none; } + +@media screen and (min-width: 30em) { + .b--dotted-ns { border-style: dotted; } + .b--dashed-ns { border-style: dashed; } + .b--solid-ns { border-style: solid; } + .b--none-ns { border-style: none; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .b--dotted-m { border-style: dotted; } + .b--dashed-m { border-style: dashed; } + .b--solid-m { border-style: solid; } + .b--none-m { border-style: none; } +} + +@media screen and (min-width: 60em) { + .b--dotted-l { border-style: dotted; } + .b--dashed-l { border-style: dashed; } + .b--solid-l { border-style: solid; } + .b--none-l { border-style: none; } +} + +/* + + BORDER WIDTHS + Docs: http://tachyons.io/docs/themes/borders/ + + Base: + bw = border-width + + Modifiers: + 0 = 0 width border + 1 = 1st step in border-width scale + 2 = 2nd step in border-width scale + 3 = 3rd step in border-width scale + 4 = 4th step in border-width scale + 5 = 5th step in border-width scale + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.bw0 { border-width: 0; } + +.bw1 { border-width: .125rem; } + +.bw2 { border-width: .25rem; } + +.bw3 { border-width: .5rem; } + +.bw4 { border-width: 1rem; } + +.bw5 { border-width: 2rem; } + +/* Resets */ + +.bt-0 { border-top-width: 0; } + +.br-0 { border-right-width: 0; } + +.bb-0 { border-bottom-width: 0; } + +.bl-0 { border-left-width: 0; } + +@media screen and (min-width: 30em) { + .bw0-ns { border-width: 0; } + .bw1-ns { border-width: .125rem; } + .bw2-ns { border-width: .25rem; } + .bw3-ns { border-width: .5rem; } + .bw4-ns { border-width: 1rem; } + .bw5-ns { border-width: 2rem; } + .bt-0-ns { border-top-width: 0; } + .br-0-ns { border-right-width: 0; } + .bb-0-ns { border-bottom-width: 0; } + .bl-0-ns { border-left-width: 0; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .bw0-m { border-width: 0; } + .bw1-m { border-width: .125rem; } + .bw2-m { border-width: .25rem; } + .bw3-m { border-width: .5rem; } + .bw4-m { border-width: 1rem; } + .bw5-m { border-width: 2rem; } + .bt-0-m { border-top-width: 0; } + .br-0-m { border-right-width: 0; } + .bb-0-m { border-bottom-width: 0; } + .bl-0-m { border-left-width: 0; } +} + +@media screen and (min-width: 60em) { + .bw0-l { border-width: 0; } + .bw1-l { border-width: .125rem; } + .bw2-l { border-width: .25rem; } + .bw3-l { border-width: .5rem; } + .bw4-l { border-width: 1rem; } + .bw5-l { border-width: 2rem; } + .bt-0-l { border-top-width: 0; } + .br-0-l { border-right-width: 0; } + .bb-0-l { border-bottom-width: 0; } + .bl-0-l { border-left-width: 0; } +} + +/* + + BOX-SHADOW + Docs: http://tachyons.io/docs/themes/box-shadow/ + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + + */ + +.shadow-1 { box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, .2); } + +.shadow-2 { box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, .2); } + +.shadow-3 { box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, .2); } + +.shadow-4 { box-shadow: 2px 2px 8px 0px rgba(0, 0, 0, .2); } + +.shadow-5 { box-shadow: 4px 4px 8px 0px rgba(0, 0, 0, .2); } + +@media screen and (min-width: 30em) { + .shadow-1-ns { box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, .2); } + .shadow-2-ns { box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, .2); } + .shadow-3-ns { box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, .2); } + .shadow-4-ns { box-shadow: 2px 2px 8px 0px rgba(0, 0, 0, .2); } + .shadow-5-ns { box-shadow: 4px 4px 8px 0px rgba(0, 0, 0, .2); } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .shadow-1-m { box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, .2); } + .shadow-2-m { box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, .2); } + .shadow-3-m { box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, .2); } + .shadow-4-m { box-shadow: 2px 2px 8px 0px rgba(0, 0, 0, .2); } + .shadow-5-m { box-shadow: 4px 4px 8px 0px rgba(0, 0, 0, .2); } +} + +@media screen and (min-width: 60em) { + .shadow-1-l { box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, .2); } + .shadow-2-l { box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, .2); } + .shadow-3-l { box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, .2); } + .shadow-4-l { box-shadow: 2px 2px 8px 0px rgba(0, 0, 0, .2); } + .shadow-5-l { box-shadow: 4px 4px 8px 0px rgba(0, 0, 0, .2); } +} + +/* + + CODE + +*/ + +.pre { + overflow-x: auto; + overflow-y: hidden; + overflow: scroll; +} + +/* + + COORDINATES + Docs: http://tachyons.io/docs/layout/position/ + + Use in combination with the position module. + + Base: + top + bottom + right + left + + Modifiers: + -0 = literal value 0 + -1 = literal value 1 + -2 = literal value 2 + --1 = literal value -1 + --2 = literal value -2 + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.top-0 { top: 0; } + +.right-0 { right: 0; } + +.bottom-0 { bottom: 0; } + +.left-0 { left: 0; } + +.top-1 { top: 1rem; } + +.right-1 { right: 1rem; } + +.bottom-1 { bottom: 1rem; } + +.left-1 { left: 1rem; } + +.top-2 { top: 2rem; } + +.right-2 { right: 2rem; } + +.bottom-2 { bottom: 2rem; } + +.left-2 { left: 2rem; } + +.top--1 { top: -1rem; } + +.right--1 { right: -1rem; } + +.bottom--1 { bottom: -1rem; } + +.left--1 { left: -1rem; } + +.top--2 { top: -2rem; } + +.right--2 { right: -2rem; } + +.bottom--2 { bottom: -2rem; } + +.left--2 { left: -2rem; } + +.absolute--fill { + top: 0; + right: 0; + bottom: 0; + left: 0; +} + +@media screen and (min-width: 30em) { + .top-0-ns { top: 0; } + .left-0-ns { left: 0; } + .right-0-ns { right: 0; } + .bottom-0-ns { bottom: 0; } + .top-1-ns { top: 1rem; } + .left-1-ns { left: 1rem; } + .right-1-ns { right: 1rem; } + .bottom-1-ns { bottom: 1rem; } + .top-2-ns { top: 2rem; } + .left-2-ns { left: 2rem; } + .right-2-ns { right: 2rem; } + .bottom-2-ns { bottom: 2rem; } + .top--1-ns { top: -1rem; } + .right--1-ns { right: -1rem; } + .bottom--1-ns { bottom: -1rem; } + .left--1-ns { left: -1rem; } + .top--2-ns { top: -2rem; } + .right--2-ns { right: -2rem; } + .bottom--2-ns { bottom: -2rem; } + .left--2-ns { left: -2rem; } + .absolute--fill-ns { + top: 0; + right: 0; + bottom: 0; + left: 0; + } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .top-0-m { top: 0; } + .left-0-m { left: 0; } + .right-0-m { right: 0; } + .bottom-0-m { bottom: 0; } + .top-1-m { top: 1rem; } + .left-1-m { left: 1rem; } + .right-1-m { right: 1rem; } + .bottom-1-m { bottom: 1rem; } + .top-2-m { top: 2rem; } + .left-2-m { left: 2rem; } + .right-2-m { right: 2rem; } + .bottom-2-m { bottom: 2rem; } + .top--1-m { top: -1rem; } + .right--1-m { right: -1rem; } + .bottom--1-m { bottom: -1rem; } + .left--1-m { left: -1rem; } + .top--2-m { top: -2rem; } + .right--2-m { right: -2rem; } + .bottom--2-m { bottom: -2rem; } + .left--2-m { left: -2rem; } + .absolute--fill-m { + top: 0; + right: 0; + bottom: 0; + left: 0; + } +} + +@media screen and (min-width: 60em) { + .top-0-l { top: 0; } + .left-0-l { left: 0; } + .right-0-l { right: 0; } + .bottom-0-l { bottom: 0; } + .top-1-l { top: 1rem; } + .left-1-l { left: 1rem; } + .right-1-l { right: 1rem; } + .bottom-1-l { bottom: 1rem; } + .top-2-l { top: 2rem; } + .left-2-l { left: 2rem; } + .right-2-l { right: 2rem; } + .bottom-2-l { bottom: 2rem; } + .top--1-l { top: -1rem; } + .right--1-l { right: -1rem; } + .bottom--1-l { bottom: -1rem; } + .left--1-l { left: -1rem; } + .top--2-l { top: -2rem; } + .right--2-l { right: -2rem; } + .bottom--2-l { bottom: -2rem; } + .left--2-l { left: -2rem; } + .absolute--fill-l { + top: 0; + right: 0; + bottom: 0; + left: 0; + } +} + +/* + + CLEARFIX + http://tachyons.io/docs/layout/clearfix/ + +*/ + +/* Nicolas Gallaghers Clearfix solution + Ref: http://nicolasgallagher.com/micro-clearfix-hack/ */ + +.cf:before, +.cf:after { content: " "; display: table; } + +.cf:after { clear: both; } + +.cf { *zoom: 1; } + +.cl { clear: left; } + +.cr { clear: right; } + +.cb { clear: both; } + +.cn { clear: none; } + +@media screen and (min-width: 30em) { + .cl-ns { clear: left; } + .cr-ns { clear: right; } + .cb-ns { clear: both; } + .cn-ns { clear: none; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .cl-m { clear: left; } + .cr-m { clear: right; } + .cb-m { clear: both; } + .cn-m { clear: none; } +} + +@media screen and (min-width: 60em) { + .cl-l { clear: left; } + .cr-l { clear: right; } + .cb-l { clear: both; } + .cn-l { clear: none; } +} + +/* + + DISPLAY + Docs: http://tachyons.io/docs/layout/display + + Base: + d = display + + Modifiers: + n = none + b = block + ib = inline-block + it = inline-table + t = table + tc = table-cell + t-row = table-row + t-columm = table-column + t-column-group = table-column-group + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.dn { display: none; } + +.di { display: inline; } + +.db { display: block; } + +.dib { display: inline-block; } + +.dit { display: inline-table; } + +.dt { display: table; } + +.dtc { display: table-cell; } + +.dt-row { display: table-row; } + +.dt-row-group { display: table-row-group; } + +.dt-column { display: table-column; } + +.dt-column-group { display: table-column-group; } + +/* + This will set table to full width and then + all cells will be equal width +*/ + +.dt--fixed { + table-layout: fixed; + width: 100%; +} + +@media screen and (min-width: 30em) { + .dn-ns { display: none; } + .di-ns { display: inline; } + .db-ns { display: block; } + .dib-ns { display: inline-block; } + .dit-ns { display: inline-table; } + .dt-ns { display: table; } + .dtc-ns { display: table-cell; } + .dt-row-ns { display: table-row; } + .dt-row-group-ns { display: table-row-group; } + .dt-column-ns { display: table-column; } + .dt-column-group-ns { display: table-column-group; } + + .dt--fixed-ns { + table-layout: fixed; + width: 100%; + } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .dn-m { display: none; } + .di-m { display: inline; } + .db-m { display: block; } + .dib-m { display: inline-block; } + .dit-m { display: inline-table; } + .dt-m { display: table; } + .dtc-m { display: table-cell; } + .dt-row-m { display: table-row; } + .dt-row-group-m { display: table-row-group; } + .dt-column-m { display: table-column; } + .dt-column-group-m { display: table-column-group; } + + .dt--fixed-m { + table-layout: fixed; + width: 100%; + } +} + +@media screen and (min-width: 60em) { + .dn-l { display: none; } + .di-l { display: inline; } + .db-l { display: block; } + .dib-l { display: inline-block; } + .dit-l { display: inline-table; } + .dt-l { display: table; } + .dtc-l { display: table-cell; } + .dt-row-l { display: table-row; } + .dt-row-group-l { display: table-row-group; } + .dt-column-l { display: table-column; } + .dt-column-group-l { display: table-column-group; } + + .dt--fixed-l { + table-layout: fixed; + width: 100%; + } +} + +/* + + FLEXBOX + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.flex { display: -webkit-box; display: -ms-flexbox; display: flex; } + +.inline-flex { display: -webkit-inline-box; display: -ms-inline-flexbox; display: inline-flex; } + +/* 1. Fix for Chrome 44 bug. + * https://code.google.com/p/chromium/issues/detail?id=506893 */ + +.flex-auto { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + min-width: 0; /* 1 */ + min-height: 0; /* 1 */ +} + +.flex-none { -webkit-box-flex: 0; -ms-flex: none; flex: none; } + +.flex-column { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } + +.flex-row { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; } + +.flex-wrap { -ms-flex-wrap: wrap; flex-wrap: wrap; } + +.flex-nowrap { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } + +.flex-wrap-reverse { -ms-flex-wrap: wrap-reverse; flex-wrap: wrap-reverse; } + +.flex-column-reverse { -webkit-box-orient: vertical; -webkit-box-direction: reverse; -ms-flex-direction: column-reverse; flex-direction: column-reverse; } + +.flex-row-reverse { -webkit-box-orient: horizontal; -webkit-box-direction: reverse; -ms-flex-direction: row-reverse; flex-direction: row-reverse; } + +.items-start { -webkit-box-align: start; -ms-flex-align: start; align-items: flex-start; } + +.items-end { -webkit-box-align: end; -ms-flex-align: end; align-items: flex-end; } + +.items-center { -webkit-box-align: center; -ms-flex-align: center; align-items: center; } + +.items-baseline { -webkit-box-align: baseline; -ms-flex-align: baseline; align-items: baseline; } + +.items-stretch { -webkit-box-align: stretch; -ms-flex-align: stretch; align-items: stretch; } + +.self-start { -ms-flex-item-align: start; align-self: flex-start; } + +.self-end { -ms-flex-item-align: end; align-self: flex-end; } + +.self-center { -ms-flex-item-align: center; -ms-grid-row-align: center; align-self: center; } + +.self-baseline { -ms-flex-item-align: baseline; align-self: baseline; } + +.self-stretch { -ms-flex-item-align: stretch; -ms-grid-row-align: stretch; align-self: stretch; } + +.justify-start { -webkit-box-pack: start; -ms-flex-pack: start; justify-content: flex-start; } + +.justify-end { -webkit-box-pack: end; -ms-flex-pack: end; justify-content: flex-end; } + +.justify-center { -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; } + +.justify-between { -webkit-box-pack: justify; -ms-flex-pack: justify; justify-content: space-between; } + +.justify-around { -ms-flex-pack: distribute; justify-content: space-around; } + +.content-start { -ms-flex-line-pack: start; align-content: flex-start; } + +.content-end { -ms-flex-line-pack: end; align-content: flex-end; } + +.content-center { -ms-flex-line-pack: center; align-content: center; } + +.content-between { -ms-flex-line-pack: justify; align-content: space-between; } + +.content-around { -ms-flex-line-pack: distribute; align-content: space-around; } + +.content-stretch { -ms-flex-line-pack: stretch; align-content: stretch; } + +.order-0 { -webkit-box-ordinal-group: 1; -ms-flex-order: 0; order: 0; } + +.order-1 { -webkit-box-ordinal-group: 2; -ms-flex-order: 1; order: 1; } + +.order-2 { -webkit-box-ordinal-group: 3; -ms-flex-order: 2; order: 2; } + +.order-3 { -webkit-box-ordinal-group: 4; -ms-flex-order: 3; order: 3; } + +.order-4 { -webkit-box-ordinal-group: 5; -ms-flex-order: 4; order: 4; } + +.order-5 { -webkit-box-ordinal-group: 6; -ms-flex-order: 5; order: 5; } + +.order-6 { -webkit-box-ordinal-group: 7; -ms-flex-order: 6; order: 6; } + +.order-7 { -webkit-box-ordinal-group: 8; -ms-flex-order: 7; order: 7; } + +.order-8 { -webkit-box-ordinal-group: 9; -ms-flex-order: 8; order: 8; } + +.order-last { -webkit-box-ordinal-group: 100000; -ms-flex-order: 99999; order: 99999; } + +.flex-grow-0 { -webkit-box-flex: 0; -ms-flex-positive: 0; flex-grow: 0; } + +.flex-grow-1 { -webkit-box-flex: 1; -ms-flex-positive: 1; flex-grow: 1; } + +.flex-shrink-0 { -ms-flex-negative: 0; flex-shrink: 0; } + +.flex-shrink-1 { -ms-flex-negative: 1; flex-shrink: 1; } + +@media screen and (min-width: 30em) { + .flex-ns { display: -webkit-box; display: -ms-flexbox; display: flex; } + .inline-flex-ns { display: -webkit-inline-box; display: -ms-inline-flexbox; display: inline-flex; } + .flex-auto-ns { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + min-width: 0; /* 1 */ + min-height: 0; /* 1 */ + } + .flex-none-ns { -webkit-box-flex: 0; -ms-flex: none; flex: none; } + .flex-column-ns { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } + .flex-row-ns { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; } + .flex-wrap-ns { -ms-flex-wrap: wrap; flex-wrap: wrap; } + .flex-nowrap-ns { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } + .flex-wrap-reverse-ns { -ms-flex-wrap: wrap-reverse; flex-wrap: wrap-reverse; } + .flex-column-reverse-ns { -webkit-box-orient: vertical; -webkit-box-direction: reverse; -ms-flex-direction: column-reverse; flex-direction: column-reverse; } + .flex-row-reverse-ns { -webkit-box-orient: horizontal; -webkit-box-direction: reverse; -ms-flex-direction: row-reverse; flex-direction: row-reverse; } + .items-start-ns { -webkit-box-align: start; -ms-flex-align: start; align-items: flex-start; } + .items-end-ns { -webkit-box-align: end; -ms-flex-align: end; align-items: flex-end; } + .items-center-ns { -webkit-box-align: center; -ms-flex-align: center; align-items: center; } + .items-baseline-ns { -webkit-box-align: baseline; -ms-flex-align: baseline; align-items: baseline; } + .items-stretch-ns { -webkit-box-align: stretch; -ms-flex-align: stretch; align-items: stretch; } + + .self-start-ns { -ms-flex-item-align: start; align-self: flex-start; } + .self-end-ns { -ms-flex-item-align: end; align-self: flex-end; } + .self-center-ns { -ms-flex-item-align: center; -ms-grid-row-align: center; align-self: center; } + .self-baseline-ns { -ms-flex-item-align: baseline; align-self: baseline; } + .self-stretch-ns { -ms-flex-item-align: stretch; -ms-grid-row-align: stretch; align-self: stretch; } + + .justify-start-ns { -webkit-box-pack: start; -ms-flex-pack: start; justify-content: flex-start; } + .justify-end-ns { -webkit-box-pack: end; -ms-flex-pack: end; justify-content: flex-end; } + .justify-center-ns { -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; } + .justify-between-ns { -webkit-box-pack: justify; -ms-flex-pack: justify; justify-content: space-between; } + .justify-around-ns { -ms-flex-pack: distribute; justify-content: space-around; } + + .content-start-ns { -ms-flex-line-pack: start; align-content: flex-start; } + .content-end-ns { -ms-flex-line-pack: end; align-content: flex-end; } + .content-center-ns { -ms-flex-line-pack: center; align-content: center; } + .content-between-ns { -ms-flex-line-pack: justify; align-content: space-between; } + .content-around-ns { -ms-flex-line-pack: distribute; align-content: space-around; } + .content-stretch-ns { -ms-flex-line-pack: stretch; align-content: stretch; } + + .order-0-ns { -webkit-box-ordinal-group: 1; -ms-flex-order: 0; order: 0; } + .order-1-ns { -webkit-box-ordinal-group: 2; -ms-flex-order: 1; order: 1; } + .order-2-ns { -webkit-box-ordinal-group: 3; -ms-flex-order: 2; order: 2; } + .order-3-ns { -webkit-box-ordinal-group: 4; -ms-flex-order: 3; order: 3; } + .order-4-ns { -webkit-box-ordinal-group: 5; -ms-flex-order: 4; order: 4; } + .order-5-ns { -webkit-box-ordinal-group: 6; -ms-flex-order: 5; order: 5; } + .order-6-ns { -webkit-box-ordinal-group: 7; -ms-flex-order: 6; order: 6; } + .order-7-ns { -webkit-box-ordinal-group: 8; -ms-flex-order: 7; order: 7; } + .order-8-ns { -webkit-box-ordinal-group: 9; -ms-flex-order: 8; order: 8; } + .order-last-ns { -webkit-box-ordinal-group: 100000; -ms-flex-order: 99999; order: 99999; } + + .flex-grow-0-ns { -webkit-box-flex: 0; -ms-flex-positive: 0; flex-grow: 0; } + .flex-grow-1-ns { -webkit-box-flex: 1; -ms-flex-positive: 1; flex-grow: 1; } + + .flex-shrink-0-ns { -ms-flex-negative: 0; flex-shrink: 0; } + .flex-shrink-1-ns { -ms-flex-negative: 1; flex-shrink: 1; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .flex-m { display: -webkit-box; display: -ms-flexbox; display: flex; } + .inline-flex-m { display: -webkit-inline-box; display: -ms-inline-flexbox; display: inline-flex; } + .flex-auto-m { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + min-width: 0; /* 1 */ + min-height: 0; /* 1 */ + } + .flex-none-m { -webkit-box-flex: 0; -ms-flex: none; flex: none; } + .flex-column-m { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } + .flex-row-m { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; } + .flex-wrap-m { -ms-flex-wrap: wrap; flex-wrap: wrap; } + .flex-nowrap-m { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } + .flex-wrap-reverse-m { -ms-flex-wrap: wrap-reverse; flex-wrap: wrap-reverse; } + .flex-column-reverse-m { -webkit-box-orient: vertical; -webkit-box-direction: reverse; -ms-flex-direction: column-reverse; flex-direction: column-reverse; } + .flex-row-reverse-m { -webkit-box-orient: horizontal; -webkit-box-direction: reverse; -ms-flex-direction: row-reverse; flex-direction: row-reverse; } + .items-start-m { -webkit-box-align: start; -ms-flex-align: start; align-items: flex-start; } + .items-end-m { -webkit-box-align: end; -ms-flex-align: end; align-items: flex-end; } + .items-center-m { -webkit-box-align: center; -ms-flex-align: center; align-items: center; } + .items-baseline-m { -webkit-box-align: baseline; -ms-flex-align: baseline; align-items: baseline; } + .items-stretch-m { -webkit-box-align: stretch; -ms-flex-align: stretch; align-items: stretch; } + + .self-start-m { -ms-flex-item-align: start; align-self: flex-start; } + .self-end-m { -ms-flex-item-align: end; align-self: flex-end; } + .self-center-m { -ms-flex-item-align: center; -ms-grid-row-align: center; align-self: center; } + .self-baseline-m { -ms-flex-item-align: baseline; align-self: baseline; } + .self-stretch-m { -ms-flex-item-align: stretch; -ms-grid-row-align: stretch; align-self: stretch; } + + .justify-start-m { -webkit-box-pack: start; -ms-flex-pack: start; justify-content: flex-start; } + .justify-end-m { -webkit-box-pack: end; -ms-flex-pack: end; justify-content: flex-end; } + .justify-center-m { -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; } + .justify-between-m { -webkit-box-pack: justify; -ms-flex-pack: justify; justify-content: space-between; } + .justify-around-m { -ms-flex-pack: distribute; justify-content: space-around; } + + .content-start-m { -ms-flex-line-pack: start; align-content: flex-start; } + .content-end-m { -ms-flex-line-pack: end; align-content: flex-end; } + .content-center-m { -ms-flex-line-pack: center; align-content: center; } + .content-between-m { -ms-flex-line-pack: justify; align-content: space-between; } + .content-around-m { -ms-flex-line-pack: distribute; align-content: space-around; } + .content-stretch-m { -ms-flex-line-pack: stretch; align-content: stretch; } + + .order-0-m { -webkit-box-ordinal-group: 1; -ms-flex-order: 0; order: 0; } + .order-1-m { -webkit-box-ordinal-group: 2; -ms-flex-order: 1; order: 1; } + .order-2-m { -webkit-box-ordinal-group: 3; -ms-flex-order: 2; order: 2; } + .order-3-m { -webkit-box-ordinal-group: 4; -ms-flex-order: 3; order: 3; } + .order-4-m { -webkit-box-ordinal-group: 5; -ms-flex-order: 4; order: 4; } + .order-5-m { -webkit-box-ordinal-group: 6; -ms-flex-order: 5; order: 5; } + .order-6-m { -webkit-box-ordinal-group: 7; -ms-flex-order: 6; order: 6; } + .order-7-m { -webkit-box-ordinal-group: 8; -ms-flex-order: 7; order: 7; } + .order-8-m { -webkit-box-ordinal-group: 9; -ms-flex-order: 8; order: 8; } + .order-last-m { -webkit-box-ordinal-group: 100000; -ms-flex-order: 99999; order: 99999; } + + .flex-grow-0-m { -webkit-box-flex: 0; -ms-flex-positive: 0; flex-grow: 0; } + .flex-grow-1-m { -webkit-box-flex: 1; -ms-flex-positive: 1; flex-grow: 1; } + + .flex-shrink-0-m { -ms-flex-negative: 0; flex-shrink: 0; } + .flex-shrink-1-m { -ms-flex-negative: 1; flex-shrink: 1; } +} + +@media screen and (min-width: 60em) { + .flex-l { display: -webkit-box; display: -ms-flexbox; display: flex; } + .inline-flex-l { display: -webkit-inline-box; display: -ms-inline-flexbox; display: inline-flex; } + .flex-auto-l { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + min-width: 0; /* 1 */ + min-height: 0; /* 1 */ + } + .flex-none-l { -webkit-box-flex: 0; -ms-flex: none; flex: none; } + .flex-column-l { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } + .flex-row-l { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; } + .flex-wrap-l { -ms-flex-wrap: wrap; flex-wrap: wrap; } + .flex-nowrap-l { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } + .flex-wrap-reverse-l { -ms-flex-wrap: wrap-reverse; flex-wrap: wrap-reverse; } + .flex-column-reverse-l { -webkit-box-orient: vertical; -webkit-box-direction: reverse; -ms-flex-direction: column-reverse; flex-direction: column-reverse; } + .flex-row-reverse-l { -webkit-box-orient: horizontal; -webkit-box-direction: reverse; -ms-flex-direction: row-reverse; flex-direction: row-reverse; } + + .items-start-l { -webkit-box-align: start; -ms-flex-align: start; align-items: flex-start; } + .items-end-l { -webkit-box-align: end; -ms-flex-align: end; align-items: flex-end; } + .items-center-l { -webkit-box-align: center; -ms-flex-align: center; align-items: center; } + .items-baseline-l { -webkit-box-align: baseline; -ms-flex-align: baseline; align-items: baseline; } + .items-stretch-l { -webkit-box-align: stretch; -ms-flex-align: stretch; align-items: stretch; } + + .self-start-l { -ms-flex-item-align: start; align-self: flex-start; } + .self-end-l { -ms-flex-item-align: end; align-self: flex-end; } + .self-center-l { -ms-flex-item-align: center; -ms-grid-row-align: center; align-self: center; } + .self-baseline-l { -ms-flex-item-align: baseline; align-self: baseline; } + .self-stretch-l { -ms-flex-item-align: stretch; -ms-grid-row-align: stretch; align-self: stretch; } + + .justify-start-l { -webkit-box-pack: start; -ms-flex-pack: start; justify-content: flex-start; } + .justify-end-l { -webkit-box-pack: end; -ms-flex-pack: end; justify-content: flex-end; } + .justify-center-l { -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; } + .justify-between-l { -webkit-box-pack: justify; -ms-flex-pack: justify; justify-content: space-between; } + .justify-around-l { -ms-flex-pack: distribute; justify-content: space-around; } + + .content-start-l { -ms-flex-line-pack: start; align-content: flex-start; } + .content-end-l { -ms-flex-line-pack: end; align-content: flex-end; } + .content-center-l { -ms-flex-line-pack: center; align-content: center; } + .content-between-l { -ms-flex-line-pack: justify; align-content: space-between; } + .content-around-l { -ms-flex-line-pack: distribute; align-content: space-around; } + .content-stretch-l { -ms-flex-line-pack: stretch; align-content: stretch; } + + .order-0-l { -webkit-box-ordinal-group: 1; -ms-flex-order: 0; order: 0; } + .order-1-l { -webkit-box-ordinal-group: 2; -ms-flex-order: 1; order: 1; } + .order-2-l { -webkit-box-ordinal-group: 3; -ms-flex-order: 2; order: 2; } + .order-3-l { -webkit-box-ordinal-group: 4; -ms-flex-order: 3; order: 3; } + .order-4-l { -webkit-box-ordinal-group: 5; -ms-flex-order: 4; order: 4; } + .order-5-l { -webkit-box-ordinal-group: 6; -ms-flex-order: 5; order: 5; } + .order-6-l { -webkit-box-ordinal-group: 7; -ms-flex-order: 6; order: 6; } + .order-7-l { -webkit-box-ordinal-group: 8; -ms-flex-order: 7; order: 7; } + .order-8-l { -webkit-box-ordinal-group: 9; -ms-flex-order: 8; order: 8; } + .order-last-l { -webkit-box-ordinal-group: 100000; -ms-flex-order: 99999; order: 99999; } + + .flex-grow-0-l { -webkit-box-flex: 0; -ms-flex-positive: 0; flex-grow: 0; } + .flex-grow-1-l { -webkit-box-flex: 1; -ms-flex-positive: 1; flex-grow: 1; } + + .flex-shrink-0-l { -ms-flex-negative: 0; flex-shrink: 0; } + .flex-shrink-1-l { -ms-flex-negative: 1; flex-shrink: 1; } +} + +/* + + FLOATS + http://tachyons.io/docs/layout/floats/ + + 1. Floated elements are automatically rendered as block level elements. + Setting floats to display inline will fix the double margin bug in + ie6. You know... just in case. + + 2. Don't forget to clearfix your floats with .cf + + Base: + f = float + + Modifiers: + l = left + r = right + n = none + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.fl { float: left; _display: inline; } + +.fr { float: right; _display: inline; } + +.fn { float: none; } + +@media screen and (min-width: 30em) { + .fl-ns { float: left; _display: inline; } + .fr-ns { float: right; _display: inline; } + .fn-ns { float: none; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .fl-m { float: left; _display: inline; } + .fr-m { float: right; _display: inline; } + .fn-m { float: none; } +} + +@media screen and (min-width: 60em) { + .fl-l { float: left; _display: inline; } + .fr-l { float: right; _display: inline; } + .fn-l { float: none; } +} + +/* + + FONT FAMILY GROUPS + Docs: http://tachyons.io/docs/typography/font-family/ + +*/ + +.sans-serif { + font-family: -apple-system, BlinkMacSystemFont, + 'avenir next', avenir, + 'helvetica neue', helvetica, + ubuntu, + roboto, noto, + 'segoe ui', arial, + sans-serif; +} + +.serif { + font-family: georgia, + times, + serif; +} + +.system-sans-serif { + font-family: sans-serif; +} + +.system-serif { + font-family: serif; +} + +/* Monospaced Typefaces (for code) */ + +/* From http://cssfontstack.com */ + +code, .code { + font-family: Consolas, + monaco, + monospace; +} + +.courier { + font-family: 'Courier Next', + courier, + monospace; +} + +/* Sans-Serif Typefaces */ + +.helvetica { + font-family: 'helvetica neue', helvetica, + sans-serif; +} + +.avenir { + font-family: 'avenir next', avenir, + sans-serif; +} + +/* Serif Typefaces */ + +.athelas { + font-family: athelas, + georgia, + serif; +} + +.georgia { + font-family: georgia, + serif; +} + +.times { + font-family: times, + serif; +} + +.bodoni { + font-family: "Bodoni MT", + serif; +} + +.calisto { + font-family: "Calisto MT", + serif; +} + +.garamond { + font-family: garamond, + serif; +} + +.baskerville { + font-family: baskerville, + serif; +} + +/* + + FONT STYLE + Docs: http://tachyons.io/docs/typography/font-style/ + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.i { font-style: italic; } + +.fs-normal { font-style: normal; } + +@media screen and (min-width: 30em) { + .i-ns { font-style: italic; } + .fs-normal-ns { font-style: normal; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .i-m { font-style: italic; } + .fs-normal-m { font-style: normal; } +} + +@media screen and (min-width: 60em) { + .i-l { font-style: italic; } + .fs-normal-l { font-style: normal; } +} + +/* + + FONT WEIGHT + Docs: http://tachyons.io/docs/typography/font-weight/ + + Base + fw = font-weight + + Modifiers: + 1 = literal value 100 + 2 = literal value 200 + 3 = literal value 300 + 4 = literal value 400 + 5 = literal value 500 + 6 = literal value 600 + 7 = literal value 700 + 8 = literal value 800 + 9 = literal value 900 + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.normal { font-weight: normal; } + +.b { font-weight: bold; } + +.fw1 { font-weight: 100; } + +.fw2 { font-weight: 200; } + +.fw3 { font-weight: 300; } + +.fw4 { font-weight: 400; } + +.fw5 { font-weight: 500; } + +.fw6 { font-weight: 600; } + +.fw7 { font-weight: 700; } + +.fw8 { font-weight: 800; } + +.fw9 { font-weight: 900; } + +@media screen and (min-width: 30em) { + .normal-ns { font-weight: normal; } + .b-ns { font-weight: bold; } + .fw1-ns { font-weight: 100; } + .fw2-ns { font-weight: 200; } + .fw3-ns { font-weight: 300; } + .fw4-ns { font-weight: 400; } + .fw5-ns { font-weight: 500; } + .fw6-ns { font-weight: 600; } + .fw7-ns { font-weight: 700; } + .fw8-ns { font-weight: 800; } + .fw9-ns { font-weight: 900; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .normal-m { font-weight: normal; } + .b-m { font-weight: bold; } + .fw1-m { font-weight: 100; } + .fw2-m { font-weight: 200; } + .fw3-m { font-weight: 300; } + .fw4-m { font-weight: 400; } + .fw5-m { font-weight: 500; } + .fw6-m { font-weight: 600; } + .fw7-m { font-weight: 700; } + .fw8-m { font-weight: 800; } + .fw9-m { font-weight: 900; } +} + +@media screen and (min-width: 60em) { + .normal-l { font-weight: normal; } + .b-l { font-weight: bold; } + .fw1-l { font-weight: 100; } + .fw2-l { font-weight: 200; } + .fw3-l { font-weight: 300; } + .fw4-l { font-weight: 400; } + .fw5-l { font-weight: 500; } + .fw6-l { font-weight: 600; } + .fw7-l { font-weight: 700; } + .fw8-l { font-weight: 800; } + .fw9-l { font-weight: 900; } +} + +/* + + FORMS + +*/ + +.input-reset { + -webkit-appearance: none; + -moz-appearance: none; +} + +.button-reset::-moz-focus-inner, +.input-reset::-moz-focus-inner { + border: 0; + padding: 0; +} + +/* + + HEIGHTS + Docs: http://tachyons.io/docs/layout/heights/ + + Base: + h = height + min-h = min-height + min-vh = min-height vertical screen height + vh = vertical screen height + + Modifiers + 1 = 1st step in height scale + 2 = 2nd step in height scale + 3 = 3rd step in height scale + 4 = 4th step in height scale + 5 = 5th step in height scale + + -25 = literal value 25% + -50 = literal value 50% + -75 = literal value 75% + -100 = literal value 100% + + -auto = string value of auto + -inherit = string value of inherit + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +/* Height Scale */ + +.h1 { height: 1rem; } + +.h2 { height: 2rem; } + +.h3 { height: 4rem; } + +.h4 { height: 8rem; } + +.h5 { height: 16rem; } + +/* Height Percentages - Based off of height of parent */ + +.h-25 { height: 25%; } + +.h-50 { height: 50%; } + +.h-75 { height: 75%; } + +.h-100 { height: 100%; } + +.min-h-100 { min-height: 100%; } + +/* Screen Height Percentage */ + +.vh-25 { height: 25vh; } + +.vh-50 { height: 50vh; } + +.vh-75 { height: 75vh; } + +.vh-100 { height: 100vh; } + +.min-vh-100 { min-height: 100vh; } + +/* String Properties */ + +.h-auto { height: auto; } + +.h-inherit { height: inherit; } + +@media screen and (min-width: 30em) { + .h1-ns { height: 1rem; } + .h2-ns { height: 2rem; } + .h3-ns { height: 4rem; } + .h4-ns { height: 8rem; } + .h5-ns { height: 16rem; } + .h-25-ns { height: 25%; } + .h-50-ns { height: 50%; } + .h-75-ns { height: 75%; } + .h-100-ns { height: 100%; } + .min-h-100-ns { min-height: 100%; } + .vh-25-ns { height: 25vh; } + .vh-50-ns { height: 50vh; } + .vh-75-ns { height: 75vh; } + .vh-100-ns { height: 100vh; } + .min-vh-100-ns { min-height: 100vh; } + .h-auto-ns { height: auto; } + .h-inherit-ns { height: inherit; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .h1-m { height: 1rem; } + .h2-m { height: 2rem; } + .h3-m { height: 4rem; } + .h4-m { height: 8rem; } + .h5-m { height: 16rem; } + .h-25-m { height: 25%; } + .h-50-m { height: 50%; } + .h-75-m { height: 75%; } + .h-100-m { height: 100%; } + .min-h-100-m { min-height: 100%; } + .vh-25-m { height: 25vh; } + .vh-50-m { height: 50vh; } + .vh-75-m { height: 75vh; } + .vh-100-m { height: 100vh; } + .min-vh-100-m { min-height: 100vh; } + .h-auto-m { height: auto; } + .h-inherit-m { height: inherit; } +} + +@media screen and (min-width: 60em) { + .h1-l { height: 1rem; } + .h2-l { height: 2rem; } + .h3-l { height: 4rem; } + .h4-l { height: 8rem; } + .h5-l { height: 16rem; } + .h-25-l { height: 25%; } + .h-50-l { height: 50%; } + .h-75-l { height: 75%; } + .h-100-l { height: 100%; } + .min-h-100-l { min-height: 100%; } + .vh-25-l { height: 25vh; } + .vh-50-l { height: 50vh; } + .vh-75-l { height: 75vh; } + .vh-100-l { height: 100vh; } + .min-vh-100-l { min-height: 100vh; } + .h-auto-l { height: auto; } + .h-inherit-l { height: inherit; } +} + +/* + + LETTER SPACING + Docs: http://tachyons.io/docs/typography/tracking/ + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.tracked { letter-spacing: .1em; } + +.tracked-tight { letter-spacing: -.05em; } + +.tracked-mega { letter-spacing: .25em; } + +@media screen and (min-width: 30em) { + .tracked-ns { letter-spacing: .1em; } + .tracked-tight-ns { letter-spacing: -.05em; } + .tracked-mega-ns { letter-spacing: .25em; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .tracked-m { letter-spacing: .1em; } + .tracked-tight-m { letter-spacing: -.05em; } + .tracked-mega-m { letter-spacing: .25em; } +} + +@media screen and (min-width: 60em) { + .tracked-l { letter-spacing: .1em; } + .tracked-tight-l { letter-spacing: -.05em; } + .tracked-mega-l { letter-spacing: .25em; } +} + +/* + + LINE HEIGHT / LEADING + Docs: http://tachyons.io/docs/typography/line-height + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.lh-solid { line-height: 1; } + +.lh-title { line-height: 1.25; } + +.lh-copy { line-height: 1.5; } + +@media screen and (min-width: 30em) { + .lh-solid-ns { line-height: 1; } + .lh-title-ns { line-height: 1.25; } + .lh-copy-ns { line-height: 1.5; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .lh-solid-m { line-height: 1; } + .lh-title-m { line-height: 1.25; } + .lh-copy-m { line-height: 1.5; } +} + +@media screen and (min-width: 60em) { + .lh-solid-l { line-height: 1; } + .lh-title-l { line-height: 1.25; } + .lh-copy-l { line-height: 1.5; } +} + +/* + + LINKS + Docs: http://tachyons.io/docs/elements/links/ + +*/ + +.link { + text-decoration: none; + transition: color .15s ease-in; +} + +.link:link, +.link:visited { + transition: color .15s ease-in; +} + +.link:hover { + transition: color .15s ease-in; +} + +.link:active { + transition: color .15s ease-in; +} + +.link:focus { + transition: color .15s ease-in; + outline: 1px dotted currentColor; +} + +/* + + LISTS + http://tachyons.io/docs/elements/lists/ + +*/ + +.list { list-style-type: none; } + +/* + + MAX WIDTHS + Docs: http://tachyons.io/docs/layout/max-widths/ + + Base: + mw = max-width + + Modifiers + 1 = 1st step in width scale + 2 = 2nd step in width scale + 3 = 3rd step in width scale + 4 = 4th step in width scale + 5 = 5th step in width scale + 6 = 6st step in width scale + 7 = 7nd step in width scale + 8 = 8rd step in width scale + 9 = 9th step in width scale + + -100 = literal value 100% + + -none = string value none + + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +/* Max Width Percentages */ + +.mw-100 { max-width: 100%; } + +/* Max Width Scale */ + +.mw1 { max-width: 1rem; } + +.mw2 { max-width: 2rem; } + +.mw3 { max-width: 4rem; } + +.mw4 { max-width: 8rem; } + +.mw5 { max-width: 16rem; } + +.mw6 { max-width: 32rem; } + +.mw7 { max-width: 48rem; } + +.mw8 { max-width: 64rem; } + +.mw9 { max-width: 96rem; } + +/* Max Width String Properties */ + +.mw-none { max-width: none; } + +@media screen and (min-width: 30em) { + .mw-100-ns { max-width: 100%; } + + .mw1-ns { max-width: 1rem; } + .mw2-ns { max-width: 2rem; } + .mw3-ns { max-width: 4rem; } + .mw4-ns { max-width: 8rem; } + .mw5-ns { max-width: 16rem; } + .mw6-ns { max-width: 32rem; } + .mw7-ns { max-width: 48rem; } + .mw8-ns { max-width: 64rem; } + .mw9-ns { max-width: 96rem; } + + .mw-none-ns { max-width: none; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .mw-100-m { max-width: 100%; } + + .mw1-m { max-width: 1rem; } + .mw2-m { max-width: 2rem; } + .mw3-m { max-width: 4rem; } + .mw4-m { max-width: 8rem; } + .mw5-m { max-width: 16rem; } + .mw6-m { max-width: 32rem; } + .mw7-m { max-width: 48rem; } + .mw8-m { max-width: 64rem; } + .mw9-m { max-width: 96rem; } + + .mw-none-m { max-width: none; } +} + +@media screen and (min-width: 60em) { + .mw-100-l { max-width: 100%; } + + .mw1-l { max-width: 1rem; } + .mw2-l { max-width: 2rem; } + .mw3-l { max-width: 4rem; } + .mw4-l { max-width: 8rem; } + .mw5-l { max-width: 16rem; } + .mw6-l { max-width: 32rem; } + .mw7-l { max-width: 48rem; } + .mw8-l { max-width: 64rem; } + .mw9-l { max-width: 96rem; } + + .mw-none-l { max-width: none; } +} + +/* + + WIDTHS + Docs: http://tachyons.io/docs/layout/widths/ + + Base: + w = width + + Modifiers + 1 = 1st step in width scale + 2 = 2nd step in width scale + 3 = 3rd step in width scale + 4 = 4th step in width scale + 5 = 5th step in width scale + + -10 = literal value 10% + -20 = literal value 20% + -25 = literal value 25% + -30 = literal value 30% + -33 = literal value 33% + -34 = literal value 34% + -40 = literal value 40% + -50 = literal value 50% + -60 = literal value 60% + -70 = literal value 70% + -75 = literal value 75% + -80 = literal value 80% + -90 = literal value 90% + -100 = literal value 100% + + -third = 100% / 3 (Not supported in opera mini or IE8) + -two-thirds = 100% / 1.5 (Not supported in opera mini or IE8) + -auto = string value auto + + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +/* Width Scale */ + +.w1 { width: 1rem; } + +.w2 { width: 2rem; } + +.w3 { width: 4rem; } + +.w4 { width: 8rem; } + +.w5 { width: 16rem; } + +.w-10 { width: 10%; } + +.w-20 { width: 20%; } + +.w-25 { width: 25%; } + +.w-30 { width: 30%; } + +.w-33 { width: 33%; } + +.w-34 { width: 34%; } + +.w-40 { width: 40%; } + +.w-50 { width: 50%; } + +.w-60 { width: 60%; } + +.w-70 { width: 70%; } + +.w-75 { width: 75%; } + +.w-80 { width: 80%; } + +.w-90 { width: 90%; } + +.w-100 { width: 100%; } + +.w-third { width: 33.33333%; } + +.w-two-thirds { width: 66.66667%; } + +.w-auto { width: auto; } + +@media screen and (min-width: 30em) { + .w1-ns { width: 1rem; } + .w2-ns { width: 2rem; } + .w3-ns { width: 4rem; } + .w4-ns { width: 8rem; } + .w5-ns { width: 16rem; } + .w-10-ns { width: 10%; } + .w-20-ns { width: 20%; } + .w-25-ns { width: 25%; } + .w-30-ns { width: 30%; } + .w-33-ns { width: 33%; } + .w-34-ns { width: 34%; } + .w-40-ns { width: 40%; } + .w-50-ns { width: 50%; } + .w-60-ns { width: 60%; } + .w-70-ns { width: 70%; } + .w-75-ns { width: 75%; } + .w-80-ns { width: 80%; } + .w-90-ns { width: 90%; } + .w-100-ns { width: 100%; } + .w-third-ns { width: 33.33333%; } + .w-two-thirds-ns { width: 66.66667%; } + .w-auto-ns { width: auto; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .w1-m { width: 1rem; } + .w2-m { width: 2rem; } + .w3-m { width: 4rem; } + .w4-m { width: 8rem; } + .w5-m { width: 16rem; } + .w-10-m { width: 10%; } + .w-20-m { width: 20%; } + .w-25-m { width: 25%; } + .w-30-m { width: 30%; } + .w-33-m { width: 33%; } + .w-34-m { width: 34%; } + .w-40-m { width: 40%; } + .w-50-m { width: 50%; } + .w-60-m { width: 60%; } + .w-70-m { width: 70%; } + .w-75-m { width: 75%; } + .w-80-m { width: 80%; } + .w-90-m { width: 90%; } + .w-100-m { width: 100%; } + .w-third-m { width: 33.33333%; } + .w-two-thirds-m { width: 66.66667%; } + .w-auto-m { width: auto; } +} + +@media screen and (min-width: 60em) { + .w1-l { width: 1rem; } + .w2-l { width: 2rem; } + .w3-l { width: 4rem; } + .w4-l { width: 8rem; } + .w5-l { width: 16rem; } + .w-10-l { width: 10%; } + .w-20-l { width: 20%; } + .w-25-l { width: 25%; } + .w-30-l { width: 30%; } + .w-33-l { width: 33%; } + .w-34-l { width: 34%; } + .w-40-l { width: 40%; } + .w-50-l { width: 50%; } + .w-60-l { width: 60%; } + .w-70-l { width: 70%; } + .w-75-l { width: 75%; } + .w-80-l { width: 80%; } + .w-90-l { width: 90%; } + .w-100-l { width: 100%; } + .w-third-l { width: 33.33333%; } + .w-two-thirds-l { width: 66.66667%; } + .w-auto-l { width: auto; } +} + +/* + + OVERFLOW + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + + */ + +.overflow-visible { overflow: visible; } + +.overflow-hidden { overflow: hidden; } + +.overflow-scroll { overflow: scroll; } + +.overflow-auto { overflow: auto; } + +.overflow-x-visible { overflow-x: visible; } + +.overflow-x-hidden { overflow-x: hidden; } + +.overflow-x-scroll { overflow-x: scroll; } + +.overflow-x-auto { overflow-x: auto; } + +.overflow-y-visible { overflow-y: visible; } + +.overflow-y-hidden { overflow-y: hidden; } + +.overflow-y-scroll { overflow-y: scroll; } + +.overflow-y-auto { overflow-y: auto; } + +@media screen and (min-width: 30em) { + .overflow-visible-ns { overflow: visible; } + .overflow-hidden-ns { overflow: hidden; } + .overflow-scroll-ns { overflow: scroll; } + .overflow-auto-ns { overflow: auto; } + .overflow-x-visible-ns { overflow-x: visible; } + .overflow-x-hidden-ns { overflow-x: hidden; } + .overflow-x-scroll-ns { overflow-x: scroll; } + .overflow-x-auto-ns { overflow-x: auto; } + + .overflow-y-visible-ns { overflow-y: visible; } + .overflow-y-hidden-ns { overflow-y: hidden; } + .overflow-y-scroll-ns { overflow-y: scroll; } + .overflow-y-auto-ns { overflow-y: auto; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .overflow-visible-m { overflow: visible; } + .overflow-hidden-m { overflow: hidden; } + .overflow-scroll-m { overflow: scroll; } + .overflow-auto-m { overflow: auto; } + + .overflow-x-visible-m { overflow-x: visible; } + .overflow-x-hidden-m { overflow-x: hidden; } + .overflow-x-scroll-m { overflow-x: scroll; } + .overflow-x-auto-m { overflow-x: auto; } + + .overflow-y-visible-m { overflow-y: visible; } + .overflow-y-hidden-m { overflow-y: hidden; } + .overflow-y-scroll-m { overflow-y: scroll; } + .overflow-y-auto-m { overflow-y: auto; } +} + +@media screen and (min-width: 60em) { + .overflow-visible-l { overflow: visible; } + .overflow-hidden-l { overflow: hidden; } + .overflow-scroll-l { overflow: scroll; } + .overflow-auto-l { overflow: auto; } + + .overflow-x-visible-l { overflow-x: visible; } + .overflow-x-hidden-l { overflow-x: hidden; } + .overflow-x-scroll-l { overflow-x: scroll; } + .overflow-x-auto-l { overflow-x: auto; } + + .overflow-y-visible-l { overflow-y: visible; } + .overflow-y-hidden-l { overflow-y: hidden; } + .overflow-y-scroll-l { overflow-y: scroll; } + .overflow-y-auto-l { overflow-y: auto; } +} + +/* + + POSITIONING + Docs: http://tachyons.io/docs/layout/position/ + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.static { position: static; } + +.relative { position: relative; } + +.absolute { position: absolute; } + +.fixed { position: fixed; } + +@media screen and (min-width: 30em) { + .static-ns { position: static; } + .relative-ns { position: relative; } + .absolute-ns { position: absolute; } + .fixed-ns { position: fixed; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .static-m { position: static; } + .relative-m { position: relative; } + .absolute-m { position: absolute; } + .fixed-m { position: fixed; } +} + +@media screen and (min-width: 60em) { + .static-l { position: static; } + .relative-l { position: relative; } + .absolute-l { position: absolute; } + .fixed-l { position: fixed; } +} + +/* + + OPACITY + Docs: http://tachyons.io/docs/themes/opacity/ + +*/ + +.o-100 { opacity: 1; } + +.o-90 { opacity: .9; } + +.o-80 { opacity: .8; } + +.o-70 { opacity: .7; } + +.o-60 { opacity: .6; } + +.o-50 { opacity: .5; } + +.o-40 { opacity: .4; } + +.o-30 { opacity: .3; } + +.o-20 { opacity: .2; } + +.o-10 { opacity: .1; } + +.o-05 { opacity: .05; } + +.o-025 { opacity: .025; } + +.o-0 { opacity: 0; } + +/* + + ROTATIONS + +*/ + +.rotate-45 { -webkit-transform: rotate(45deg); transform: rotate(45deg); } + +.rotate-90 { -webkit-transform: rotate(90deg); transform: rotate(90deg); } + +.rotate-135 { -webkit-transform: rotate(135deg); transform: rotate(135deg); } + +.rotate-180 { -webkit-transform: rotate(180deg); transform: rotate(180deg); } + +.rotate-225 { -webkit-transform: rotate(225deg); transform: rotate(225deg); } + +.rotate-270 { -webkit-transform: rotate(270deg); transform: rotate(270deg); } + +.rotate-315 { -webkit-transform: rotate(315deg); transform: rotate(315deg); } + +@media screen and (min-width: 30em){ + .rotate-45-ns { -webkit-transform: rotate(45deg); transform: rotate(45deg); } + .rotate-90-ns { -webkit-transform: rotate(90deg); transform: rotate(90deg); } + .rotate-135-ns { -webkit-transform: rotate(135deg); transform: rotate(135deg); } + .rotate-180-ns { -webkit-transform: rotate(180deg); transform: rotate(180deg); } + .rotate-225-ns { -webkit-transform: rotate(225deg); transform: rotate(225deg); } + .rotate-270-ns { -webkit-transform: rotate(270deg); transform: rotate(270deg); } + .rotate-315-ns { -webkit-transform: rotate(315deg); transform: rotate(315deg); } +} + +@media screen and (min-width: 30em) and (max-width: 60em){ + .rotate-45-m { -webkit-transform: rotate(45deg); transform: rotate(45deg); } + .rotate-90-m { -webkit-transform: rotate(90deg); transform: rotate(90deg); } + .rotate-135-m { -webkit-transform: rotate(135deg); transform: rotate(135deg); } + .rotate-180-m { -webkit-transform: rotate(180deg); transform: rotate(180deg); } + .rotate-225-m { -webkit-transform: rotate(225deg); transform: rotate(225deg); } + .rotate-270-m { -webkit-transform: rotate(270deg); transform: rotate(270deg); } + .rotate-315-m { -webkit-transform: rotate(315deg); transform: rotate(315deg); } +} + +@media screen and (min-width: 60em){ + .rotate-45-l { -webkit-transform: rotate(45deg); transform: rotate(45deg); } + .rotate-90-l { -webkit-transform: rotate(90deg); transform: rotate(90deg); } + .rotate-135-l { -webkit-transform: rotate(135deg); transform: rotate(135deg); } + .rotate-180-l { -webkit-transform: rotate(180deg); transform: rotate(180deg); } + .rotate-225-l { -webkit-transform: rotate(225deg); transform: rotate(225deg); } + .rotate-270-l { -webkit-transform: rotate(270deg); transform: rotate(270deg); } + .rotate-315-l { -webkit-transform: rotate(315deg); transform: rotate(315deg); } +} + +/* + + SKINS + Docs: http://tachyons.io/docs/themes/skins/ + + Classes for setting foreground and background colors on elements. + If you haven't declared a border color, but set border on an element, it will + be set to the current text color. + +*/ + +/* Text colors */ + +.black-90 { color: rgba(0, 0, 0, .9); } + +.black-80 { color: rgba(0, 0, 0, .8); } + +.black-70 { color: rgba(0, 0, 0, .7); } + +.black-60 { color: rgba(0, 0, 0, .6); } + +.black-50 { color: rgba(0, 0, 0, .5); } + +.black-40 { color: rgba(0, 0, 0, .4); } + +.black-30 { color: rgba(0, 0, 0, .3); } + +.black-20 { color: rgba(0, 0, 0, .2); } + +.black-10 { color: rgba(0, 0, 0, .1); } + +.black-05 { color: rgba(0, 0, 0, .05); } + +.white-90 { color: rgba(255, 255, 255, .9); } + +.white-80 { color: rgba(255, 255, 255, .8); } + +.white-70 { color: rgba(255, 255, 255, .7); } + +.white-60 { color: rgba(255, 255, 255, .6); } + +.white-50 { color: rgba(255, 255, 255, .5); } + +.white-40 { color: rgba(255, 255, 255, .4); } + +.white-30 { color: rgba(255, 255, 255, .3); } + +.white-20 { color: rgba(255, 255, 255, .2); } + +.white-10 { color: rgba(255, 255, 255, .1); } + +.black { color: #000; } + +.near-black { color: #111; } + +.dark-gray { color: #333; } + +.mid-gray { color: #555; } + +.gray { color: #777; } + +.silver { color: #999; } + +.light-silver { color: #aaa; } + +.moon-gray { color: #ccc; } + +.light-gray { color: #eee; } + +.near-white { color: #f4f4f4; } + +.white { color: #fff; } + +.dark-red { color: #e7040f; } + +.red { color: #ff4136; } + +.light-red { color: #ff725c; } + +.orange { color: #ff6300; } + +.gold { color: #ffb700; } + +.yellow { color: #ffd700; } + +.light-yellow { color: #fbf1a9; } + +.purple { color: #5e2ca5; } + +.light-purple { color: #a463f2; } + +.dark-pink { color: #d5008f; } + +.hot-pink { color: #ff41b4; } + +.pink { color: #ff80cc; } + +.light-pink { color: #ffa3d7; } + +.dark-green { color: #137752; } + +.green { color: #19a974; } + +.light-green { color: #9eebcf; } + +.navy { color: #001b44; } + +.dark-blue { color: #00449e; } + +.blue { color: #357edd; } + +.light-blue { color: #96ccff; } + +.lightest-blue { color: #cdecff; } + +.washed-blue { color: #f6fffe; } + +.washed-green { color: #e8fdf5; } + +.washed-yellow { color: #fffceb; } + +.washed-red { color: #ffdfdf; } + +.color-inherit { color: inherit; } + +.bg-black-90 { background-color: rgba(0, 0, 0, .9); } + +.bg-black-80 { background-color: rgba(0, 0, 0, .8); } + +.bg-black-70 { background-color: rgba(0, 0, 0, .7); } + +.bg-black-60 { background-color: rgba(0, 0, 0, .6); } + +.bg-black-50 { background-color: rgba(0, 0, 0, .5); } + +.bg-black-40 { background-color: rgba(0, 0, 0, .4); } + +.bg-black-30 { background-color: rgba(0, 0, 0, .3); } + +.bg-black-20 { background-color: rgba(0, 0, 0, .2); } + +.bg-black-10 { background-color: rgba(0, 0, 0, .1); } + +.bg-black-05 { background-color: rgba(0, 0, 0, .05); } + +.bg-white-90 { background-color: rgba(255, 255, 255, .9); } + +.bg-white-80 { background-color: rgba(255, 255, 255, .8); } + +.bg-white-70 { background-color: rgba(255, 255, 255, .7); } + +.bg-white-60 { background-color: rgba(255, 255, 255, .6); } + +.bg-white-50 { background-color: rgba(255, 255, 255, .5); } + +.bg-white-40 { background-color: rgba(255, 255, 255, .4); } + +.bg-white-30 { background-color: rgba(255, 255, 255, .3); } + +.bg-white-20 { background-color: rgba(255, 255, 255, .2); } + +.bg-white-10 { background-color: rgba(255, 255, 255, .1); } + +/* Background colors */ + +.bg-black { background-color: #000; } + +.bg-near-black { background-color: #111; } + +.bg-dark-gray { background-color: #333; } + +.bg-mid-gray { background-color: #555; } + +.bg-gray { background-color: #777; } + +.bg-silver { background-color: #999; } + +.bg-light-silver { background-color: #aaa; } + +.bg-moon-gray { background-color: #ccc; } + +.bg-light-gray { background-color: #eee; } + +.bg-near-white { background-color: #f4f4f4; } + +.bg-white { background-color: #fff; } + +.bg-transparent { background-color: transparent; } + +.bg-dark-red { background-color: #e7040f; } + +.bg-red { background-color: #ff4136; } + +.bg-light-red { background-color: #ff725c; } + +.bg-orange { background-color: #ff6300; } + +.bg-gold { background-color: #ffb700; } + +.bg-yellow { background-color: #ffd700; } + +.bg-light-yellow { background-color: #fbf1a9; } + +.bg-purple { background-color: #5e2ca5; } + +.bg-light-purple { background-color: #a463f2; } + +.bg-dark-pink { background-color: #d5008f; } + +.bg-hot-pink { background-color: #ff41b4; } + +.bg-pink { background-color: #ff80cc; } + +.bg-light-pink { background-color: #ffa3d7; } + +.bg-dark-green { background-color: #137752; } + +.bg-green { background-color: #19a974; } + +.bg-light-green { background-color: #9eebcf; } + +.bg-navy { background-color: #001b44; } + +.bg-dark-blue { background-color: #00449e; } + +.bg-blue { background-color: #357edd; } + +.bg-light-blue { background-color: #96ccff; } + +.bg-lightest-blue { background-color: #cdecff; } + +.bg-washed-blue { background-color: #f6fffe; } + +.bg-washed-green { background-color: #e8fdf5; } + +.bg-washed-yellow { background-color: #fffceb; } + +.bg-washed-red { background-color: #ffdfdf; } + +.bg-inherit { background-color: inherit; } + +/* + + SKINS:PSEUDO + + Customize the color of an element when + it is focused or hovered over. + + */ + +.hover-black:hover, +.hover-black:focus { color: #000; } + +.hover-near-black:hover, +.hover-near-black:focus { color: #111; } + +.hover-dark-gray:hover, +.hover-dark-gray:focus { color: #333; } + +.hover-mid-gray:hover, +.hover-mid-gray:focus { color: #555; } + +.hover-gray:hover, +.hover-gray:focus { color: #777; } + +.hover-silver:hover, +.hover-silver:focus { color: #999; } + +.hover-light-silver:hover, +.hover-light-silver:focus { color: #aaa; } + +.hover-moon-gray:hover, +.hover-moon-gray:focus { color: #ccc; } + +.hover-light-gray:hover, +.hover-light-gray:focus { color: #eee; } + +.hover-near-white:hover, +.hover-near-white:focus { color: #f4f4f4; } + +.hover-white:hover, +.hover-white:focus { color: #fff; } + +.hover-black-90:hover, +.hover-black-90:focus { color: rgba(0, 0, 0, .9); } + +.hover-black-80:hover, +.hover-black-80:focus { color: rgba(0, 0, 0, .8); } + +.hover-black-70:hover, +.hover-black-70:focus { color: rgba(0, 0, 0, .7); } + +.hover-black-60:hover, +.hover-black-60:focus { color: rgba(0, 0, 0, .6); } + +.hover-black-50:hover, +.hover-black-50:focus { color: rgba(0, 0, 0, .5); } + +.hover-black-40:hover, +.hover-black-40:focus { color: rgba(0, 0, 0, .4); } + +.hover-black-30:hover, +.hover-black-30:focus { color: rgba(0, 0, 0, .3); } + +.hover-black-20:hover, +.hover-black-20:focus { color: rgba(0, 0, 0, .2); } + +.hover-black-10:hover, +.hover-black-10:focus { color: rgba(0, 0, 0, .1); } + +.hover-white-90:hover, +.hover-white-90:focus { color: rgba(255, 255, 255, .9); } + +.hover-white-80:hover, +.hover-white-80:focus { color: rgba(255, 255, 255, .8); } + +.hover-white-70:hover, +.hover-white-70:focus { color: rgba(255, 255, 255, .7); } + +.hover-white-60:hover, +.hover-white-60:focus { color: rgba(255, 255, 255, .6); } + +.hover-white-50:hover, +.hover-white-50:focus { color: rgba(255, 255, 255, .5); } + +.hover-white-40:hover, +.hover-white-40:focus { color: rgba(255, 255, 255, .4); } + +.hover-white-30:hover, +.hover-white-30:focus { color: rgba(255, 255, 255, .3); } + +.hover-white-20:hover, +.hover-white-20:focus { color: rgba(255, 255, 255, .2); } + +.hover-white-10:hover, +.hover-white-10:focus { color: rgba(255, 255, 255, .1); } + +.hover-inherit:hover, +.hover-inherit:focus { color: inherit; } + +.hover-bg-black:hover, +.hover-bg-black:focus { background-color: #000; } + +.hover-bg-near-black:hover, +.hover-bg-near-black:focus { background-color: #111; } + +.hover-bg-dark-gray:hover, +.hover-bg-dark-gray:focus { background-color: #333; } + +.hover-bg-mid-gray:hover, +.hover-bg-mid-gray:focus { background-color: #555; } + +.hover-bg-gray:hover, +.hover-bg-gray:focus { background-color: #777; } + +.hover-bg-silver:hover, +.hover-bg-silver:focus { background-color: #999; } + +.hover-bg-light-silver:hover, +.hover-bg-light-silver:focus { background-color: #aaa; } + +.hover-bg-moon-gray:hover, +.hover-bg-moon-gray:focus { background-color: #ccc; } + +.hover-bg-light-gray:hover, +.hover-bg-light-gray:focus { background-color: #eee; } + +.hover-bg-near-white:hover, +.hover-bg-near-white:focus { background-color: #f4f4f4; } + +.hover-bg-white:hover, +.hover-bg-white:focus { background-color: #fff; } + +.hover-bg-transparent:hover, +.hover-bg-transparent:focus { background-color: transparent; } + +.hover-bg-black-90:hover, +.hover-bg-black-90:focus { background-color: rgba(0, 0, 0, .9); } + +.hover-bg-black-80:hover, +.hover-bg-black-80:focus { background-color: rgba(0, 0, 0, .8); } + +.hover-bg-black-70:hover, +.hover-bg-black-70:focus { background-color: rgba(0, 0, 0, .7); } + +.hover-bg-black-60:hover, +.hover-bg-black-60:focus { background-color: rgba(0, 0, 0, .6); } + +.hover-bg-black-50:hover, +.hover-bg-black-50:focus { background-color: rgba(0, 0, 0, .5); } + +.hover-bg-black-40:hover, +.hover-bg-black-40:focus { background-color: rgba(0, 0, 0, .4); } + +.hover-bg-black-30:hover, +.hover-bg-black-30:focus { background-color: rgba(0, 0, 0, .3); } + +.hover-bg-black-20:hover, +.hover-bg-black-20:focus { background-color: rgba(0, 0, 0, .2); } + +.hover-bg-black-10:hover, +.hover-bg-black-10:focus { background-color: rgba(0, 0, 0, .1); } + +.hover-bg-white-90:hover, +.hover-bg-white-90:focus { background-color: rgba(255, 255, 255, .9); } + +.hover-bg-white-80:hover, +.hover-bg-white-80:focus { background-color: rgba(255, 255, 255, .8); } + +.hover-bg-white-70:hover, +.hover-bg-white-70:focus { background-color: rgba(255, 255, 255, .7); } + +.hover-bg-white-60:hover, +.hover-bg-white-60:focus { background-color: rgba(255, 255, 255, .6); } + +.hover-bg-white-50:hover, +.hover-bg-white-50:focus { background-color: rgba(255, 255, 255, .5); } + +.hover-bg-white-40:hover, +.hover-bg-white-40:focus { background-color: rgba(255, 255, 255, .4); } + +.hover-bg-white-30:hover, +.hover-bg-white-30:focus { background-color: rgba(255, 255, 255, .3); } + +.hover-bg-white-20:hover, +.hover-bg-white-20:focus { background-color: rgba(255, 255, 255, .2); } + +.hover-bg-white-10:hover, +.hover-bg-white-10:focus { background-color: rgba(255, 255, 255, .1); } + +.hover-dark-red:hover, +.hover-dark-red:focus { color: #e7040f; } + +.hover-red:hover, +.hover-red:focus { color: #ff4136; } + +.hover-light-red:hover, +.hover-light-red:focus { color: #ff725c; } + +.hover-orange:hover, +.hover-orange:focus { color: #ff6300; } + +.hover-gold:hover, +.hover-gold:focus { color: #ffb700; } + +.hover-yellow:hover, +.hover-yellow:focus { color: #ffd700; } + +.hover-light-yellow:hover, +.hover-light-yellow:focus { color: #fbf1a9; } + +.hover-purple:hover, +.hover-purple:focus { color: #5e2ca5; } + +.hover-light-purple:hover, +.hover-light-purple:focus { color: #a463f2; } + +.hover-dark-pink:hover, +.hover-dark-pink:focus { color: #d5008f; } + +.hover-hot-pink:hover, +.hover-hot-pink:focus { color: #ff41b4; } + +.hover-pink:hover, +.hover-pink:focus { color: #ff80cc; } + +.hover-light-pink:hover, +.hover-light-pink:focus { color: #ffa3d7; } + +.hover-dark-green:hover, +.hover-dark-green:focus { color: #137752; } + +.hover-green:hover, +.hover-green:focus { color: #19a974; } + +.hover-light-green:hover, +.hover-light-green:focus { color: #9eebcf; } + +.hover-navy:hover, +.hover-navy:focus { color: #001b44; } + +.hover-dark-blue:hover, +.hover-dark-blue:focus { color: #00449e; } + +.hover-blue:hover, +.hover-blue:focus { color: #357edd; } + +.hover-light-blue:hover, +.hover-light-blue:focus { color: #96ccff; } + +.hover-lightest-blue:hover, +.hover-lightest-blue:focus { color: #cdecff; } + +.hover-washed-blue:hover, +.hover-washed-blue:focus { color: #f6fffe; } + +.hover-washed-green:hover, +.hover-washed-green:focus { color: #e8fdf5; } + +.hover-washed-yellow:hover, +.hover-washed-yellow:focus { color: #fffceb; } + +.hover-washed-red:hover, +.hover-washed-red:focus { color: #ffdfdf; } + +.hover-bg-dark-red:hover, +.hover-bg-dark-red:focus { background-color: #e7040f; } + +.hover-bg-red:hover, +.hover-bg-red:focus { background-color: #ff4136; } + +.hover-bg-light-red:hover, +.hover-bg-light-red:focus { background-color: #ff725c; } + +.hover-bg-orange:hover, +.hover-bg-orange:focus { background-color: #ff6300; } + +.hover-bg-gold:hover, +.hover-bg-gold:focus { background-color: #ffb700; } + +.hover-bg-yellow:hover, +.hover-bg-yellow:focus { background-color: #ffd700; } + +.hover-bg-light-yellow:hover, +.hover-bg-light-yellow:focus { background-color: #fbf1a9; } + +.hover-bg-purple:hover, +.hover-bg-purple:focus { background-color: #5e2ca5; } + +.hover-bg-light-purple:hover, +.hover-bg-light-purple:focus { background-color: #a463f2; } + +.hover-bg-dark-pink:hover, +.hover-bg-dark-pink:focus { background-color: #d5008f; } + +.hover-bg-hot-pink:hover, +.hover-bg-hot-pink:focus { background-color: #ff41b4; } + +.hover-bg-pink:hover, +.hover-bg-pink:focus { background-color: #ff80cc; } + +.hover-bg-light-pink:hover, +.hover-bg-light-pink:focus { background-color: #ffa3d7; } + +.hover-bg-dark-green:hover, +.hover-bg-dark-green:focus { background-color: #137752; } + +.hover-bg-green:hover, +.hover-bg-green:focus { background-color: #19a974; } + +.hover-bg-light-green:hover, +.hover-bg-light-green:focus { background-color: #9eebcf; } + +.hover-bg-navy:hover, +.hover-bg-navy:focus { background-color: #001b44; } + +.hover-bg-dark-blue:hover, +.hover-bg-dark-blue:focus { background-color: #00449e; } + +.hover-bg-blue:hover, +.hover-bg-blue:focus { background-color: #357edd; } + +.hover-bg-light-blue:hover, +.hover-bg-light-blue:focus { background-color: #96ccff; } + +.hover-bg-lightest-blue:hover, +.hover-bg-lightest-blue:focus { background-color: #cdecff; } + +.hover-bg-washed-blue:hover, +.hover-bg-washed-blue:focus { background-color: #f6fffe; } + +.hover-bg-washed-green:hover, +.hover-bg-washed-green:focus { background-color: #e8fdf5; } + +.hover-bg-washed-yellow:hover, +.hover-bg-washed-yellow:focus { background-color: #fffceb; } + +.hover-bg-washed-red:hover, +.hover-bg-washed-red:focus { background-color: #ffdfdf; } + +.hover-bg-inherit:hover, +.hover-bg-inherit:focus { background-color: inherit; } + +/* Variables */ + +/* + SPACING + Docs: http://tachyons.io/docs/layout/spacing/ + + An eight step powers of two scale ranging from 0 to 16rem. + + Base: + p = padding + m = margin + + Modifiers: + a = all + h = horizontal + v = vertical + t = top + r = right + b = bottom + l = left + + 0 = none + 1 = 1st step in spacing scale + 2 = 2nd step in spacing scale + 3 = 3rd step in spacing scale + 4 = 4th step in spacing scale + 5 = 5th step in spacing scale + 6 = 6th step in spacing scale + 7 = 7th step in spacing scale + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.pa0 { padding: 0; } + +.pa1 { padding: .25rem; } + +.pa2 { padding: .5rem; } + +.pa3 { padding: 1rem; } + +.pa4 { padding: 2rem; } + +.pa5 { padding: 4rem; } + +.pa6 { padding: 8rem; } + +.pa7 { padding: 16rem; } + +.pl0 { padding-left: 0; } + +.pl1 { padding-left: .25rem; } + +.pl2 { padding-left: .5rem; } + +.pl3 { padding-left: 1rem; } + +.pl4 { padding-left: 2rem; } + +.pl5 { padding-left: 4rem; } + +.pl6 { padding-left: 8rem; } + +.pl7 { padding-left: 16rem; } + +.pr0 { padding-right: 0; } + +.pr1 { padding-right: .25rem; } + +.pr2 { padding-right: .5rem; } + +.pr3 { padding-right: 1rem; } + +.pr4 { padding-right: 2rem; } + +.pr5 { padding-right: 4rem; } + +.pr6 { padding-right: 8rem; } + +.pr7 { padding-right: 16rem; } + +.pb0 { padding-bottom: 0; } + +.pb1 { padding-bottom: .25rem; } + +.pb2 { padding-bottom: .5rem; } + +.pb3 { padding-bottom: 1rem; } + +.pb4 { padding-bottom: 2rem; } + +.pb5 { padding-bottom: 4rem; } + +.pb6 { padding-bottom: 8rem; } + +.pb7 { padding-bottom: 16rem; } + +.pt0 { padding-top: 0; } + +.pt1 { padding-top: .25rem; } + +.pt2 { padding-top: .5rem; } + +.pt3 { padding-top: 1rem; } + +.pt4 { padding-top: 2rem; } + +.pt5 { padding-top: 4rem; } + +.pt6 { padding-top: 8rem; } + +.pt7 { padding-top: 16rem; } + +.pv0 { + padding-top: 0; + padding-bottom: 0; +} + +.pv1 { + padding-top: .25rem; + padding-bottom: .25rem; +} + +.pv2 { + padding-top: .5rem; + padding-bottom: .5rem; +} + +.pv3 { + padding-top: 1rem; + padding-bottom: 1rem; +} + +.pv4 { + padding-top: 2rem; + padding-bottom: 2rem; +} + +.pv5 { + padding-top: 4rem; + padding-bottom: 4rem; +} + +.pv6 { + padding-top: 8rem; + padding-bottom: 8rem; +} + +.pv7 { + padding-top: 16rem; + padding-bottom: 16rem; +} + +.ph0 { + padding-left: 0; + padding-right: 0; +} + +.ph1 { + padding-left: .25rem; + padding-right: .25rem; +} + +.ph2 { + padding-left: .5rem; + padding-right: .5rem; +} + +.ph3 { + padding-left: 1rem; + padding-right: 1rem; +} + +.ph4 { + padding-left: 2rem; + padding-right: 2rem; +} + +.ph5 { + padding-left: 4rem; + padding-right: 4rem; +} + +.ph6 { + padding-left: 8rem; + padding-right: 8rem; +} + +.ph7 { + padding-left: 16rem; + padding-right: 16rem; +} + +.ma0 { margin: 0; } + +.ma1 { margin: .25rem; } + +.ma2 { margin: .5rem; } + +.ma3 { margin: 1rem; } + +.ma4 { margin: 2rem; } + +.ma5 { margin: 4rem; } + +.ma6 { margin: 8rem; } + +.ma7 { margin: 16rem; } + +.ml0 { margin-left: 0; } + +.ml1 { margin-left: .25rem; } + +.ml2 { margin-left: .5rem; } + +.ml3 { margin-left: 1rem; } + +.ml4 { margin-left: 2rem; } + +.ml5 { margin-left: 4rem; } + +.ml6 { margin-left: 8rem; } + +.ml7 { margin-left: 16rem; } + +.mr0 { margin-right: 0; } + +.mr1 { margin-right: .25rem; } + +.mr2 { margin-right: .5rem; } + +.mr3 { margin-right: 1rem; } + +.mr4 { margin-right: 2rem; } + +.mr5 { margin-right: 4rem; } + +.mr6 { margin-right: 8rem; } + +.mr7 { margin-right: 16rem; } + +.mb0 { margin-bottom: 0; } + +.mb1 { margin-bottom: .25rem; } + +.mb2 { margin-bottom: .5rem; } + +.mb3 { margin-bottom: 1rem; } + +.mb4 { margin-bottom: 2rem; } + +.mb5 { margin-bottom: 4rem; } + +.mb6 { margin-bottom: 8rem; } + +.mb7 { margin-bottom: 16rem; } + +.mt0 { margin-top: 0; } + +.mt1 { margin-top: .25rem; } + +.mt2 { margin-top: .5rem; } + +.mt3 { margin-top: 1rem; } + +.mt4 { margin-top: 2rem; } + +.mt5 { margin-top: 4rem; } + +.mt6 { margin-top: 8rem; } + +.mt7 { margin-top: 16rem; } + +.mv0 { + margin-top: 0; + margin-bottom: 0; +} + +.mv1 { + margin-top: .25rem; + margin-bottom: .25rem; +} + +.mv2 { + margin-top: .5rem; + margin-bottom: .5rem; +} + +.mv3 { + margin-top: 1rem; + margin-bottom: 1rem; +} + +.mv4 { + margin-top: 2rem; + margin-bottom: 2rem; +} + +.mv5 { + margin-top: 4rem; + margin-bottom: 4rem; +} + +.mv6 { + margin-top: 8rem; + margin-bottom: 8rem; +} + +.mv7 { + margin-top: 16rem; + margin-bottom: 16rem; +} + +.mh0 { + margin-left: 0; + margin-right: 0; +} + +.mh1 { + margin-left: .25rem; + margin-right: .25rem; +} + +.mh2 { + margin-left: .5rem; + margin-right: .5rem; +} + +.mh3 { + margin-left: 1rem; + margin-right: 1rem; +} + +.mh4 { + margin-left: 2rem; + margin-right: 2rem; +} + +.mh5 { + margin-left: 4rem; + margin-right: 4rem; +} + +.mh6 { + margin-left: 8rem; + margin-right: 8rem; +} + +.mh7 { + margin-left: 16rem; + margin-right: 16rem; +} + +@media screen and (min-width: 30em) { + .pa0-ns { padding: 0; } + .pa1-ns { padding: .25rem; } + .pa2-ns { padding: .5rem; } + .pa3-ns { padding: 1rem; } + .pa4-ns { padding: 2rem; } + .pa5-ns { padding: 4rem; } + .pa6-ns { padding: 8rem; } + .pa7-ns { padding: 16rem; } + + .pl0-ns { padding-left: 0; } + .pl1-ns { padding-left: .25rem; } + .pl2-ns { padding-left: .5rem; } + .pl3-ns { padding-left: 1rem; } + .pl4-ns { padding-left: 2rem; } + .pl5-ns { padding-left: 4rem; } + .pl6-ns { padding-left: 8rem; } + .pl7-ns { padding-left: 16rem; } + + .pr0-ns { padding-right: 0; } + .pr1-ns { padding-right: .25rem; } + .pr2-ns { padding-right: .5rem; } + .pr3-ns { padding-right: 1rem; } + .pr4-ns { padding-right: 2rem; } + .pr5-ns { padding-right: 4rem; } + .pr6-ns { padding-right: 8rem; } + .pr7-ns { padding-right: 16rem; } + + .pb0-ns { padding-bottom: 0; } + .pb1-ns { padding-bottom: .25rem; } + .pb2-ns { padding-bottom: .5rem; } + .pb3-ns { padding-bottom: 1rem; } + .pb4-ns { padding-bottom: 2rem; } + .pb5-ns { padding-bottom: 4rem; } + .pb6-ns { padding-bottom: 8rem; } + .pb7-ns { padding-bottom: 16rem; } + + .pt0-ns { padding-top: 0; } + .pt1-ns { padding-top: .25rem; } + .pt2-ns { padding-top: .5rem; } + .pt3-ns { padding-top: 1rem; } + .pt4-ns { padding-top: 2rem; } + .pt5-ns { padding-top: 4rem; } + .pt6-ns { padding-top: 8rem; } + .pt7-ns { padding-top: 16rem; } + + .pv0-ns { + padding-top: 0; + padding-bottom: 0; + } + .pv1-ns { + padding-top: .25rem; + padding-bottom: .25rem; + } + .pv2-ns { + padding-top: .5rem; + padding-bottom: .5rem; + } + .pv3-ns { + padding-top: 1rem; + padding-bottom: 1rem; + } + .pv4-ns { + padding-top: 2rem; + padding-bottom: 2rem; + } + .pv5-ns { + padding-top: 4rem; + padding-bottom: 4rem; + } + .pv6-ns { + padding-top: 8rem; + padding-bottom: 8rem; + } + .pv7-ns { + padding-top: 16rem; + padding-bottom: 16rem; + } + .ph0-ns { + padding-left: 0; + padding-right: 0; + } + .ph1-ns { + padding-left: .25rem; + padding-right: .25rem; + } + .ph2-ns { + padding-left: .5rem; + padding-right: .5rem; + } + .ph3-ns { + padding-left: 1rem; + padding-right: 1rem; + } + .ph4-ns { + padding-left: 2rem; + padding-right: 2rem; + } + .ph5-ns { + padding-left: 4rem; + padding-right: 4rem; + } + .ph6-ns { + padding-left: 8rem; + padding-right: 8rem; + } + .ph7-ns { + padding-left: 16rem; + padding-right: 16rem; + } + + .ma0-ns { margin: 0; } + .ma1-ns { margin: .25rem; } + .ma2-ns { margin: .5rem; } + .ma3-ns { margin: 1rem; } + .ma4-ns { margin: 2rem; } + .ma5-ns { margin: 4rem; } + .ma6-ns { margin: 8rem; } + .ma7-ns { margin: 16rem; } + + .ml0-ns { margin-left: 0; } + .ml1-ns { margin-left: .25rem; } + .ml2-ns { margin-left: .5rem; } + .ml3-ns { margin-left: 1rem; } + .ml4-ns { margin-left: 2rem; } + .ml5-ns { margin-left: 4rem; } + .ml6-ns { margin-left: 8rem; } + .ml7-ns { margin-left: 16rem; } + + .mr0-ns { margin-right: 0; } + .mr1-ns { margin-right: .25rem; } + .mr2-ns { margin-right: .5rem; } + .mr3-ns { margin-right: 1rem; } + .mr4-ns { margin-right: 2rem; } + .mr5-ns { margin-right: 4rem; } + .mr6-ns { margin-right: 8rem; } + .mr7-ns { margin-right: 16rem; } + + .mb0-ns { margin-bottom: 0; } + .mb1-ns { margin-bottom: .25rem; } + .mb2-ns { margin-bottom: .5rem; } + .mb3-ns { margin-bottom: 1rem; } + .mb4-ns { margin-bottom: 2rem; } + .mb5-ns { margin-bottom: 4rem; } + .mb6-ns { margin-bottom: 8rem; } + .mb7-ns { margin-bottom: 16rem; } + + .mt0-ns { margin-top: 0; } + .mt1-ns { margin-top: .25rem; } + .mt2-ns { margin-top: .5rem; } + .mt3-ns { margin-top: 1rem; } + .mt4-ns { margin-top: 2rem; } + .mt5-ns { margin-top: 4rem; } + .mt6-ns { margin-top: 8rem; } + .mt7-ns { margin-top: 16rem; } + + .mv0-ns { + margin-top: 0; + margin-bottom: 0; + } + .mv1-ns { + margin-top: .25rem; + margin-bottom: .25rem; + } + .mv2-ns { + margin-top: .5rem; + margin-bottom: .5rem; + } + .mv3-ns { + margin-top: 1rem; + margin-bottom: 1rem; + } + .mv4-ns { + margin-top: 2rem; + margin-bottom: 2rem; + } + .mv5-ns { + margin-top: 4rem; + margin-bottom: 4rem; + } + .mv6-ns { + margin-top: 8rem; + margin-bottom: 8rem; + } + .mv7-ns { + margin-top: 16rem; + margin-bottom: 16rem; + } + + .mh0-ns { + margin-left: 0; + margin-right: 0; + } + .mh1-ns { + margin-left: .25rem; + margin-right: .25rem; + } + .mh2-ns { + margin-left: .5rem; + margin-right: .5rem; + } + .mh3-ns { + margin-left: 1rem; + margin-right: 1rem; + } + .mh4-ns { + margin-left: 2rem; + margin-right: 2rem; + } + .mh5-ns { + margin-left: 4rem; + margin-right: 4rem; + } + .mh6-ns { + margin-left: 8rem; + margin-right: 8rem; + } + .mh7-ns { + margin-left: 16rem; + margin-right: 16rem; + } + +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .pa0-m { padding: 0; } + .pa1-m { padding: .25rem; } + .pa2-m { padding: .5rem; } + .pa3-m { padding: 1rem; } + .pa4-m { padding: 2rem; } + .pa5-m { padding: 4rem; } + .pa6-m { padding: 8rem; } + .pa7-m { padding: 16rem; } + + .pl0-m { padding-left: 0; } + .pl1-m { padding-left: .25rem; } + .pl2-m { padding-left: .5rem; } + .pl3-m { padding-left: 1rem; } + .pl4-m { padding-left: 2rem; } + .pl5-m { padding-left: 4rem; } + .pl6-m { padding-left: 8rem; } + .pl7-m { padding-left: 16rem; } + + .pr0-m { padding-right: 0; } + .pr1-m { padding-right: .25rem; } + .pr2-m { padding-right: .5rem; } + .pr3-m { padding-right: 1rem; } + .pr4-m { padding-right: 2rem; } + .pr5-m { padding-right: 4rem; } + .pr6-m { padding-right: 8rem; } + .pr7-m { padding-right: 16rem; } + + .pb0-m { padding-bottom: 0; } + .pb1-m { padding-bottom: .25rem; } + .pb2-m { padding-bottom: .5rem; } + .pb3-m { padding-bottom: 1rem; } + .pb4-m { padding-bottom: 2rem; } + .pb5-m { padding-bottom: 4rem; } + .pb6-m { padding-bottom: 8rem; } + .pb7-m { padding-bottom: 16rem; } + + .pt0-m { padding-top: 0; } + .pt1-m { padding-top: .25rem; } + .pt2-m { padding-top: .5rem; } + .pt3-m { padding-top: 1rem; } + .pt4-m { padding-top: 2rem; } + .pt5-m { padding-top: 4rem; } + .pt6-m { padding-top: 8rem; } + .pt7-m { padding-top: 16rem; } + + .pv0-m { + padding-top: 0; + padding-bottom: 0; + } + .pv1-m { + padding-top: .25rem; + padding-bottom: .25rem; + } + .pv2-m { + padding-top: .5rem; + padding-bottom: .5rem; + } + .pv3-m { + padding-top: 1rem; + padding-bottom: 1rem; + } + .pv4-m { + padding-top: 2rem; + padding-bottom: 2rem; + } + .pv5-m { + padding-top: 4rem; + padding-bottom: 4rem; + } + .pv6-m { + padding-top: 8rem; + padding-bottom: 8rem; + } + .pv7-m { + padding-top: 16rem; + padding-bottom: 16rem; + } + + .ph0-m { + padding-left: 0; + padding-right: 0; + } + .ph1-m { + padding-left: .25rem; + padding-right: .25rem; + } + .ph2-m { + padding-left: .5rem; + padding-right: .5rem; + } + .ph3-m { + padding-left: 1rem; + padding-right: 1rem; + } + .ph4-m { + padding-left: 2rem; + padding-right: 2rem; + } + .ph5-m { + padding-left: 4rem; + padding-right: 4rem; + } + .ph6-m { + padding-left: 8rem; + padding-right: 8rem; + } + .ph7-m { + padding-left: 16rem; + padding-right: 16rem; + } + + .ma0-m { margin: 0; } + .ma1-m { margin: .25rem; } + .ma2-m { margin: .5rem; } + .ma3-m { margin: 1rem; } + .ma4-m { margin: 2rem; } + .ma5-m { margin: 4rem; } + .ma6-m { margin: 8rem; } + .ma7-m { margin: 16rem; } + + .ml0-m { margin-left: 0; } + .ml1-m { margin-left: .25rem; } + .ml2-m { margin-left: .5rem; } + .ml3-m { margin-left: 1rem; } + .ml4-m { margin-left: 2rem; } + .ml5-m { margin-left: 4rem; } + .ml6-m { margin-left: 8rem; } + .ml7-m { margin-left: 16rem; } + + .mr0-m { margin-right: 0; } + .mr1-m { margin-right: .25rem; } + .mr2-m { margin-right: .5rem; } + .mr3-m { margin-right: 1rem; } + .mr4-m { margin-right: 2rem; } + .mr5-m { margin-right: 4rem; } + .mr6-m { margin-right: 8rem; } + .mr7-m { margin-right: 16rem; } + + .mb0-m { margin-bottom: 0; } + .mb1-m { margin-bottom: .25rem; } + .mb2-m { margin-bottom: .5rem; } + .mb3-m { margin-bottom: 1rem; } + .mb4-m { margin-bottom: 2rem; } + .mb5-m { margin-bottom: 4rem; } + .mb6-m { margin-bottom: 8rem; } + .mb7-m { margin-bottom: 16rem; } + + .mt0-m { margin-top: 0; } + .mt1-m { margin-top: .25rem; } + .mt2-m { margin-top: .5rem; } + .mt3-m { margin-top: 1rem; } + .mt4-m { margin-top: 2rem; } + .mt5-m { margin-top: 4rem; } + .mt6-m { margin-top: 8rem; } + .mt7-m { margin-top: 16rem; } + + .mv0-m { + margin-top: 0; + margin-bottom: 0; + } + .mv1-m { + margin-top: .25rem; + margin-bottom: .25rem; + } + .mv2-m { + margin-top: .5rem; + margin-bottom: .5rem; + } + .mv3-m { + margin-top: 1rem; + margin-bottom: 1rem; + } + .mv4-m { + margin-top: 2rem; + margin-bottom: 2rem; + } + .mv5-m { + margin-top: 4rem; + margin-bottom: 4rem; + } + .mv6-m { + margin-top: 8rem; + margin-bottom: 8rem; + } + .mv7-m { + margin-top: 16rem; + margin-bottom: 16rem; + } + + .mh0-m { + margin-left: 0; + margin-right: 0; + } + .mh1-m { + margin-left: .25rem; + margin-right: .25rem; + } + .mh2-m { + margin-left: .5rem; + margin-right: .5rem; + } + .mh3-m { + margin-left: 1rem; + margin-right: 1rem; + } + .mh4-m { + margin-left: 2rem; + margin-right: 2rem; + } + .mh5-m { + margin-left: 4rem; + margin-right: 4rem; + } + .mh6-m { + margin-left: 8rem; + margin-right: 8rem; + } + .mh7-m { + margin-left: 16rem; + margin-right: 16rem; + } + +} + +@media screen and (min-width: 60em) { + .pa0-l { padding: 0; } + .pa1-l { padding: .25rem; } + .pa2-l { padding: .5rem; } + .pa3-l { padding: 1rem; } + .pa4-l { padding: 2rem; } + .pa5-l { padding: 4rem; } + .pa6-l { padding: 8rem; } + .pa7-l { padding: 16rem; } + + .pl0-l { padding-left: 0; } + .pl1-l { padding-left: .25rem; } + .pl2-l { padding-left: .5rem; } + .pl3-l { padding-left: 1rem; } + .pl4-l { padding-left: 2rem; } + .pl5-l { padding-left: 4rem; } + .pl6-l { padding-left: 8rem; } + .pl7-l { padding-left: 16rem; } + + .pr0-l { padding-right: 0; } + .pr1-l { padding-right: .25rem; } + .pr2-l { padding-right: .5rem; } + .pr3-l { padding-right: 1rem; } + .pr4-l { padding-right: 2rem; } + .pr5-l { padding-right: 4rem; } + .pr6-l { padding-right: 8rem; } + .pr7-l { padding-right: 16rem; } + + .pb0-l { padding-bottom: 0; } + .pb1-l { padding-bottom: .25rem; } + .pb2-l { padding-bottom: .5rem; } + .pb3-l { padding-bottom: 1rem; } + .pb4-l { padding-bottom: 2rem; } + .pb5-l { padding-bottom: 4rem; } + .pb6-l { padding-bottom: 8rem; } + .pb7-l { padding-bottom: 16rem; } + + .pt0-l { padding-top: 0; } + .pt1-l { padding-top: .25rem; } + .pt2-l { padding-top: .5rem; } + .pt3-l { padding-top: 1rem; } + .pt4-l { padding-top: 2rem; } + .pt5-l { padding-top: 4rem; } + .pt6-l { padding-top: 8rem; } + .pt7-l { padding-top: 16rem; } + + .pv0-l { + padding-top: 0; + padding-bottom: 0; + } + .pv1-l { + padding-top: .25rem; + padding-bottom: .25rem; + } + .pv2-l { + padding-top: .5rem; + padding-bottom: .5rem; + } + .pv3-l { + padding-top: 1rem; + padding-bottom: 1rem; + } + .pv4-l { + padding-top: 2rem; + padding-bottom: 2rem; + } + .pv5-l { + padding-top: 4rem; + padding-bottom: 4rem; + } + .pv6-l { + padding-top: 8rem; + padding-bottom: 8rem; + } + .pv7-l { + padding-top: 16rem; + padding-bottom: 16rem; + } + + .ph0-l { + padding-left: 0; + padding-right: 0; + } + .ph1-l { + padding-left: .25rem; + padding-right: .25rem; + } + .ph2-l { + padding-left: .5rem; + padding-right: .5rem; + } + .ph3-l { + padding-left: 1rem; + padding-right: 1rem; + } + .ph4-l { + padding-left: 2rem; + padding-right: 2rem; + } + .ph5-l { + padding-left: 4rem; + padding-right: 4rem; + } + .ph6-l { + padding-left: 8rem; + padding-right: 8rem; + } + .ph7-l { + padding-left: 16rem; + padding-right: 16rem; + } + + .ma0-l { margin: 0; } + .ma1-l { margin: .25rem; } + .ma2-l { margin: .5rem; } + .ma3-l { margin: 1rem; } + .ma4-l { margin: 2rem; } + .ma5-l { margin: 4rem; } + .ma6-l { margin: 8rem; } + .ma7-l { margin: 16rem; } + + .ml0-l { margin-left: 0; } + .ml1-l { margin-left: .25rem; } + .ml2-l { margin-left: .5rem; } + .ml3-l { margin-left: 1rem; } + .ml4-l { margin-left: 2rem; } + .ml5-l { margin-left: 4rem; } + .ml6-l { margin-left: 8rem; } + .ml7-l { margin-left: 16rem; } + + .mr0-l { margin-right: 0; } + .mr1-l { margin-right: .25rem; } + .mr2-l { margin-right: .5rem; } + .mr3-l { margin-right: 1rem; } + .mr4-l { margin-right: 2rem; } + .mr5-l { margin-right: 4rem; } + .mr6-l { margin-right: 8rem; } + .mr7-l { margin-right: 16rem; } + + .mb0-l { margin-bottom: 0; } + .mb1-l { margin-bottom: .25rem; } + .mb2-l { margin-bottom: .5rem; } + .mb3-l { margin-bottom: 1rem; } + .mb4-l { margin-bottom: 2rem; } + .mb5-l { margin-bottom: 4rem; } + .mb6-l { margin-bottom: 8rem; } + .mb7-l { margin-bottom: 16rem; } + + .mt0-l { margin-top: 0; } + .mt1-l { margin-top: .25rem; } + .mt2-l { margin-top: .5rem; } + .mt3-l { margin-top: 1rem; } + .mt4-l { margin-top: 2rem; } + .mt5-l { margin-top: 4rem; } + .mt6-l { margin-top: 8rem; } + .mt7-l { margin-top: 16rem; } + + .mv0-l { + margin-top: 0; + margin-bottom: 0; + } + .mv1-l { + margin-top: .25rem; + margin-bottom: .25rem; + } + .mv2-l { + margin-top: .5rem; + margin-bottom: .5rem; + } + .mv3-l { + margin-top: 1rem; + margin-bottom: 1rem; + } + .mv4-l { + margin-top: 2rem; + margin-bottom: 2rem; + } + .mv5-l { + margin-top: 4rem; + margin-bottom: 4rem; + } + .mv6-l { + margin-top: 8rem; + margin-bottom: 8rem; + } + .mv7-l { + margin-top: 16rem; + margin-bottom: 16rem; + } + + .mh0-l { + margin-left: 0; + margin-right: 0; + } + .mh1-l { + margin-left: .25rem; + margin-right: .25rem; + } + .mh2-l { + margin-left: .5rem; + margin-right: .5rem; + } + .mh3-l { + margin-left: 1rem; + margin-right: 1rem; + } + .mh4-l { + margin-left: 2rem; + margin-right: 2rem; + } + .mh5-l { + margin-left: 4rem; + margin-right: 4rem; + } + .mh6-l { + margin-left: 8rem; + margin-right: 8rem; + } + .mh7-l { + margin-left: 16rem; + margin-right: 16rem; + } +} + +/* + NEGATIVE MARGINS + + Base: + n = negative + + Modifiers: + a = all + t = top + r = right + b = bottom + l = left + + 1 = 1st step in spacing scale + 2 = 2nd step in spacing scale + 3 = 3rd step in spacing scale + 4 = 4th step in spacing scale + 5 = 5th step in spacing scale + 6 = 6th step in spacing scale + 7 = 7th step in spacing scale + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.na1 { margin: -0.25rem; } + +.na2 { margin: -0.5rem; } + +.na3 { margin: -1rem; } + +.na4 { margin: -2rem; } + +.na5 { margin: -4rem; } + +.na6 { margin: -8rem; } + +.na7 { margin: -16rem; } + +.nl1 { margin-left: -0.25rem; } + +.nl2 { margin-left: -0.5rem; } + +.nl3 { margin-left: -1rem; } + +.nl4 { margin-left: -2rem; } + +.nl5 { margin-left: -4rem; } + +.nl6 { margin-left: -8rem; } + +.nl7 { margin-left: -16rem; } + +.nr1 { margin-right: -0.25rem; } + +.nr2 { margin-right: -0.5rem; } + +.nr3 { margin-right: -1rem; } + +.nr4 { margin-right: -2rem; } + +.nr5 { margin-right: -4rem; } + +.nr6 { margin-right: -8rem; } + +.nr7 { margin-right: -16rem; } + +.nb1 { margin-bottom: -0.25rem; } + +.nb2 { margin-bottom: -0.5rem; } + +.nb3 { margin-bottom: -1rem; } + +.nb4 { margin-bottom: -2rem; } + +.nb5 { margin-bottom: -4rem; } + +.nb6 { margin-bottom: -8rem; } + +.nb7 { margin-bottom: -16rem; } + +.nt1 { margin-top: -0.25rem; } + +.nt2 { margin-top: -0.5rem; } + +.nt3 { margin-top: -1rem; } + +.nt4 { margin-top: -2rem; } + +.nt5 { margin-top: -4rem; } + +.nt6 { margin-top: -8rem; } + +.nt7 { margin-top: -16rem; } + +@media screen and (min-width: 30em) { + + .na1-ns { margin: -0.25rem; } + .na2-ns { margin: -0.5rem; } + .na3-ns { margin: -1rem; } + .na4-ns { margin: -2rem; } + .na5-ns { margin: -4rem; } + .na6-ns { margin: -8rem; } + .na7-ns { margin: -16rem; } + + .nl1-ns { margin-left: -0.25rem; } + .nl2-ns { margin-left: -0.5rem; } + .nl3-ns { margin-left: -1rem; } + .nl4-ns { margin-left: -2rem; } + .nl5-ns { margin-left: -4rem; } + .nl6-ns { margin-left: -8rem; } + .nl7-ns { margin-left: -16rem; } + + .nr1-ns { margin-right: -0.25rem; } + .nr2-ns { margin-right: -0.5rem; } + .nr3-ns { margin-right: -1rem; } + .nr4-ns { margin-right: -2rem; } + .nr5-ns { margin-right: -4rem; } + .nr6-ns { margin-right: -8rem; } + .nr7-ns { margin-right: -16rem; } + + .nb1-ns { margin-bottom: -0.25rem; } + .nb2-ns { margin-bottom: -0.5rem; } + .nb3-ns { margin-bottom: -1rem; } + .nb4-ns { margin-bottom: -2rem; } + .nb5-ns { margin-bottom: -4rem; } + .nb6-ns { margin-bottom: -8rem; } + .nb7-ns { margin-bottom: -16rem; } + + .nt1-ns { margin-top: -0.25rem; } + .nt2-ns { margin-top: -0.5rem; } + .nt3-ns { margin-top: -1rem; } + .nt4-ns { margin-top: -2rem; } + .nt5-ns { margin-top: -4rem; } + .nt6-ns { margin-top: -8rem; } + .nt7-ns { margin-top: -16rem; } + +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .na1-m { margin: -0.25rem; } + .na2-m { margin: -0.5rem; } + .na3-m { margin: -1rem; } + .na4-m { margin: -2rem; } + .na5-m { margin: -4rem; } + .na6-m { margin: -8rem; } + .na7-m { margin: -16rem; } + + .nl1-m { margin-left: -0.25rem; } + .nl2-m { margin-left: -0.5rem; } + .nl3-m { margin-left: -1rem; } + .nl4-m { margin-left: -2rem; } + .nl5-m { margin-left: -4rem; } + .nl6-m { margin-left: -8rem; } + .nl7-m { margin-left: -16rem; } + + .nr1-m { margin-right: -0.25rem; } + .nr2-m { margin-right: -0.5rem; } + .nr3-m { margin-right: -1rem; } + .nr4-m { margin-right: -2rem; } + .nr5-m { margin-right: -4rem; } + .nr6-m { margin-right: -8rem; } + .nr7-m { margin-right: -16rem; } + + .nb1-m { margin-bottom: -0.25rem; } + .nb2-m { margin-bottom: -0.5rem; } + .nb3-m { margin-bottom: -1rem; } + .nb4-m { margin-bottom: -2rem; } + .nb5-m { margin-bottom: -4rem; } + .nb6-m { margin-bottom: -8rem; } + .nb7-m { margin-bottom: -16rem; } + + .nt1-m { margin-top: -0.25rem; } + .nt2-m { margin-top: -0.5rem; } + .nt3-m { margin-top: -1rem; } + .nt4-m { margin-top: -2rem; } + .nt5-m { margin-top: -4rem; } + .nt6-m { margin-top: -8rem; } + .nt7-m { margin-top: -16rem; } + +} + +@media screen and (min-width: 60em) { + .na1-l { margin: -0.25rem; } + .na2-l { margin: -0.5rem; } + .na3-l { margin: -1rem; } + .na4-l { margin: -2rem; } + .na5-l { margin: -4rem; } + .na6-l { margin: -8rem; } + .na7-l { margin: -16rem; } + + .nl1-l { margin-left: -0.25rem; } + .nl2-l { margin-left: -0.5rem; } + .nl3-l { margin-left: -1rem; } + .nl4-l { margin-left: -2rem; } + .nl5-l { margin-left: -4rem; } + .nl6-l { margin-left: -8rem; } + .nl7-l { margin-left: -16rem; } + + .nr1-l { margin-right: -0.25rem; } + .nr2-l { margin-right: -0.5rem; } + .nr3-l { margin-right: -1rem; } + .nr4-l { margin-right: -2rem; } + .nr5-l { margin-right: -4rem; } + .nr6-l { margin-right: -8rem; } + .nr7-l { margin-right: -16rem; } + + .nb1-l { margin-bottom: -0.25rem; } + .nb2-l { margin-bottom: -0.5rem; } + .nb3-l { margin-bottom: -1rem; } + .nb4-l { margin-bottom: -2rem; } + .nb5-l { margin-bottom: -4rem; } + .nb6-l { margin-bottom: -8rem; } + .nb7-l { margin-bottom: -16rem; } + + .nt1-l { margin-top: -0.25rem; } + .nt2-l { margin-top: -0.5rem; } + .nt3-l { margin-top: -1rem; } + .nt4-l { margin-top: -2rem; } + .nt5-l { margin-top: -4rem; } + .nt6-l { margin-top: -8rem; } + .nt7-l { margin-top: -16rem; } +} + +/* + + TABLES + Docs: http://tachyons.io/docs/elements/tables/ + +*/ + +.collapse { + border-collapse: collapse; + border-spacing: 0; +} + +.striped--light-silver:nth-child(odd) { + background-color: #aaa; +} + +.striped--moon-gray:nth-child(odd) { + background-color: #ccc; +} + +.striped--light-gray:nth-child(odd) { + background-color: #eee; +} + +.striped--near-white:nth-child(odd) { + background-color: #f4f4f4; +} + +.stripe-light:nth-child(odd) { + background-color: rgba(255, 255, 255, .1); +} + +.stripe-dark:nth-child(odd) { + background-color: rgba(0, 0, 0, .1); +} + +/* + + TEXT DECORATION + Docs: http://tachyons.io/docs/typography/text-decoration/ + + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.strike { text-decoration: line-through; } + +.underline { text-decoration: underline; } + +.no-underline { text-decoration: none; } + +@media screen and (min-width: 30em) { + .strike-ns { text-decoration: line-through; } + .underline-ns { text-decoration: underline; } + .no-underline-ns { text-decoration: none; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .strike-m { text-decoration: line-through; } + .underline-m { text-decoration: underline; } + .no-underline-m { text-decoration: none; } +} + +@media screen and (min-width: 60em) { + .strike-l { text-decoration: line-through; } + .underline-l { text-decoration: underline; } + .no-underline-l { text-decoration: none; } +} + +/* + + TEXT ALIGN + Docs: http://tachyons.io/docs/typography/text-align/ + + Base + t = text-align + + Modifiers + l = left + r = right + c = center + j = justify + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.tl { text-align: left; } + +.tr { text-align: right; } + +.tc { text-align: center; } + +.tj { text-align: justify; } + +@media screen and (min-width: 30em) { + .tl-ns { text-align: left; } + .tr-ns { text-align: right; } + .tc-ns { text-align: center; } + .tj-ns { text-align: justify; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .tl-m { text-align: left; } + .tr-m { text-align: right; } + .tc-m { text-align: center; } + .tj-m { text-align: justify; } +} + +@media screen and (min-width: 60em) { + .tl-l { text-align: left; } + .tr-l { text-align: right; } + .tc-l { text-align: center; } + .tj-l { text-align: justify; } +} + +/* + + TEXT TRANSFORM + Docs: http://tachyons.io/docs/typography/text-transform/ + + Base: + tt = text-transform + + Modifiers + c = capitalize + l = lowercase + u = uppercase + n = none + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.ttc { text-transform: capitalize; } + +.ttl { text-transform: lowercase; } + +.ttu { text-transform: uppercase; } + +.ttn { text-transform: none; } + +@media screen and (min-width: 30em) { + .ttc-ns { text-transform: capitalize; } + .ttl-ns { text-transform: lowercase; } + .ttu-ns { text-transform: uppercase; } + .ttn-ns { text-transform: none; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .ttc-m { text-transform: capitalize; } + .ttl-m { text-transform: lowercase; } + .ttu-m { text-transform: uppercase; } + .ttn-m { text-transform: none; } +} + +@media screen and (min-width: 60em) { + .ttc-l { text-transform: capitalize; } + .ttl-l { text-transform: lowercase; } + .ttu-l { text-transform: uppercase; } + .ttn-l { text-transform: none; } +} + +/* + + TYPE SCALE + Docs: http://tachyons.io/docs/typography/scale/ + + Base: + f = font-size + + Modifiers + 1 = 1st step in size scale + 2 = 2nd step in size scale + 3 = 3rd step in size scale + 4 = 4th step in size scale + 5 = 5th step in size scale + 6 = 6th step in size scale + 7 = 7th step in size scale + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large +*/ + +/* + * For Hero/Marketing Titles + * + * These generally are too large for mobile + * so be careful using them on smaller screens. + * */ + +.f-6, +.f-headline { + font-size: 6rem; +} + +.f-5, +.f-subheadline { + font-size: 5rem; +} + +/* Type Scale */ + +.f1 { font-size: 3rem; } + +.f2 { font-size: 2.25rem; } + +.f3 { font-size: 1.5rem; } + +.f4 { font-size: 1.25rem; } + +.f5 { font-size: 1rem; } + +.f6 { font-size: .875rem; } + +.f7 { font-size: .75rem; } + +/* Small and hard to read for many people so use with extreme caution */ + +@media screen and (min-width: 30em){ + .f-6-ns, + .f-headline-ns { font-size: 6rem; } + .f-5-ns, + .f-subheadline-ns { font-size: 5rem; } + .f1-ns { font-size: 3rem; } + .f2-ns { font-size: 2.25rem; } + .f3-ns { font-size: 1.5rem; } + .f4-ns { font-size: 1.25rem; } + .f5-ns { font-size: 1rem; } + .f6-ns { font-size: .875rem; } + .f7-ns { font-size: .75rem; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .f-6-m, + .f-headline-m { font-size: 6rem; } + .f-5-m, + .f-subheadline-m { font-size: 5rem; } + .f1-m { font-size: 3rem; } + .f2-m { font-size: 2.25rem; } + .f3-m { font-size: 1.5rem; } + .f4-m { font-size: 1.25rem; } + .f5-m { font-size: 1rem; } + .f6-m { font-size: .875rem; } + .f7-m { font-size: .75rem; } +} + +@media screen and (min-width: 60em) { + .f-6-l, + .f-headline-l { + font-size: 6rem; + } + .f-5-l, + .f-subheadline-l { + font-size: 5rem; + } + .f1-l { font-size: 3rem; } + .f2-l { font-size: 2.25rem; } + .f3-l { font-size: 1.5rem; } + .f4-l { font-size: 1.25rem; } + .f5-l { font-size: 1rem; } + .f6-l { font-size: .875rem; } + .f7-l { font-size: .75rem; } +} + +/* + + TYPOGRAPHY + http://tachyons.io/docs/typography/measure/ + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +/* Measure is limited to ~66 characters */ + +.measure { + max-width: 30em; +} + +/* Measure is limited to ~80 characters */ + +.measure-wide { + max-width: 34em; +} + +/* Measure is limited to ~45 characters */ + +.measure-narrow { + max-width: 20em; +} + +/* Book paragraph style - paragraphs are indented with no vertical spacing. */ + +.indent { + text-indent: 1em; + margin-top: 0; + margin-bottom: 0; +} + +.small-caps { + -webkit-font-feature-settings: "c2sc"; + font-feature-settings: "c2sc"; + font-variant: small-caps; +} + +/* Combine this class with a width to truncate text (or just leave as is to truncate at width of containing element. */ + +.truncate { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +@media screen and (min-width: 30em) { + .measure-ns { + max-width: 30em; + } + .measure-wide-ns { + max-width: 34em; + } + .measure-narrow-ns { + max-width: 20em; + } + .indent-ns { + text-indent: 1em; + margin-top: 0; + margin-bottom: 0; + } + .small-caps-ns { + -webkit-font-feature-settings: "c2sc"; + font-feature-settings: "c2sc"; + font-variant: small-caps; + } + .truncate-ns { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .measure-m { + max-width: 30em; + } + .measure-wide-m { + max-width: 34em; + } + .measure-narrow-m { + max-width: 20em; + } + .indent-m { + text-indent: 1em; + margin-top: 0; + margin-bottom: 0; + } + .small-caps-m { + -webkit-font-feature-settings: "c2sc"; + font-feature-settings: "c2sc"; + font-variant: small-caps; + } + .truncate-m { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +} + +@media screen and (min-width: 60em) { + .measure-l { + max-width: 30em; + } + .measure-wide-l { + max-width: 34em; + } + .measure-narrow-l { + max-width: 20em; + } + .indent-l { + text-indent: 1em; + margin-top: 0; + margin-bottom: 0; + } + .small-caps-l { + -webkit-font-feature-settings: "c2sc"; + font-feature-settings: "c2sc"; + font-variant: small-caps; + } + .truncate-l { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +} + +/* + + UTILITIES + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +/* Equivalent to .overflow-y-scroll */ + +.overflow-container { + overflow-y: scroll; +} + +.center { + margin-right: auto; + margin-left: auto; +} + +.mr-auto { margin-right: auto; } + +.ml-auto { margin-left: auto; } + +@media screen and (min-width: 30em){ + .center-ns { + margin-right: auto; + margin-left: auto; + } + .mr-auto-ns { margin-right: auto; } + .ml-auto-ns { margin-left: auto; } +} + +@media screen and (min-width: 30em) and (max-width: 60em){ + .center-m { + margin-right: auto; + margin-left: auto; + } + .mr-auto-m { margin-right: auto; } + .ml-auto-m { margin-left: auto; } +} + +@media screen and (min-width: 60em){ + .center-l { + margin-right: auto; + margin-left: auto; + } + .mr-auto-l { margin-right: auto; } + .ml-auto-l { margin-left: auto; } +} + +/* + + VISIBILITY + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +/* + Text that is hidden but accessible + Ref: http://snook.ca/archives/html_and_css/hiding-content-for-accessibility +*/ + +.clip { + position: fixed !important; + _position: absolute !important; + clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ + clip: rect(1px, 1px, 1px, 1px); +} + +@media screen and (min-width: 30em) { + .clip-ns { + position: fixed !important; + _position: absolute !important; + clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ + clip: rect(1px, 1px, 1px, 1px); + } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .clip-m { + position: fixed !important; + _position: absolute !important; + clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ + clip: rect(1px, 1px, 1px, 1px); + } +} + +@media screen and (min-width: 60em) { + .clip-l { + position: fixed !important; + _position: absolute !important; + clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ + clip: rect(1px, 1px, 1px, 1px); + } +} + +/* + + WHITE SPACE + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.ws-normal { white-space: normal; } + +.nowrap { white-space: nowrap; } + +.pre { white-space: pre; } + +@media screen and (min-width: 30em) { + .ws-normal-ns { white-space: normal; } + .nowrap-ns { white-space: nowrap; } + .pre-ns { white-space: pre; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .ws-normal-m { white-space: normal; } + .nowrap-m { white-space: nowrap; } + .pre-m { white-space: pre; } +} + +@media screen and (min-width: 60em) { + .ws-normal-l { white-space: normal; } + .nowrap-l { white-space: nowrap; } + .pre-l { white-space: pre; } +} + +/* + + VERTICAL ALIGN + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.v-base { vertical-align: baseline; } + +.v-mid { vertical-align: middle; } + +.v-top { vertical-align: top; } + +.v-btm { vertical-align: bottom; } + +@media screen and (min-width: 30em) { + .v-base-ns { vertical-align: baseline; } + .v-mid-ns { vertical-align: middle; } + .v-top-ns { vertical-align: top; } + .v-btm-ns { vertical-align: bottom; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .v-base-m { vertical-align: baseline; } + .v-mid-m { vertical-align: middle; } + .v-top-m { vertical-align: top; } + .v-btm-m { vertical-align: bottom; } +} + +@media screen and (min-width: 60em) { + .v-base-l { vertical-align: baseline; } + .v-mid-l { vertical-align: middle; } + .v-top-l { vertical-align: top; } + .v-btm-l { vertical-align: bottom; } +} + +/* + + HOVER EFFECTS + Docs: http://tachyons.io/docs/themes/hovers/ + + - Dim + - Glow + - Hide Child + - Underline text + - Grow + - Pointer + - Shadow + +*/ + +/* + + Dim element on hover by adding the dim class. + +*/ + +.dim { + opacity: 1; + transition: opacity .15s ease-in; +} + +.dim:hover, +.dim:focus { + opacity: .5; + transition: opacity .15s ease-in; +} + +.dim:active { + opacity: .8; transition: opacity .15s ease-out; +} + +/* + + Animate opacity to 100% on hover by adding the glow class. + +*/ + +.glow { + transition: opacity .15s ease-in; +} + +.glow:hover, +.glow:focus { + opacity: 1; + transition: opacity .15s ease-in; +} + +/* + + Hide child & reveal on hover: + + Put the hide-child class on a parent element and any nested element with the + child class will be hidden and displayed on hover or focus. + +
+
Hidden until hover or focus
+
Hidden until hover or focus
+
Hidden until hover or focus
+
Hidden until hover or focus
+
+*/ + +.hide-child .child { + opacity: 0; + transition: opacity .15s ease-in; +} + +.hide-child:hover .child, +.hide-child:focus .child, +.hide-child:active .child { + opacity: 1; + transition: opacity .15s ease-in; +} + +.underline-hover:hover, +.underline-hover:focus { + text-decoration: underline; +} + +/* Can combine this with overflow-hidden to make background images grow on hover + * even if you are using background-size: cover */ + +.grow { + -moz-osx-font-smoothing: grayscale; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-transform: translateZ(0); + transform: translateZ(0); + transition: -webkit-transform 0.25s ease-out; + transition: transform 0.25s ease-out; + transition: transform 0.25s ease-out, -webkit-transform 0.25s ease-out; +} + +.grow:hover, +.grow:focus { + -webkit-transform: scale(1.05); + transform: scale(1.05); +} + +.grow:active { + -webkit-transform: scale(.90); + transform: scale(.90); +} + +.grow-large { + -moz-osx-font-smoothing: grayscale; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-transform: translateZ(0); + transform: translateZ(0); + transition: -webkit-transform .25s ease-in-out; + transition: transform .25s ease-in-out; + transition: transform .25s ease-in-out, -webkit-transform .25s ease-in-out; +} + +.grow-large:hover, +.grow-large:focus { + -webkit-transform: scale(1.2); + transform: scale(1.2); +} + +.grow-large:active { + -webkit-transform: scale(.95); + transform: scale(.95); +} + +/* Add pointer on hover */ + +.pointer:hover { + cursor: pointer; +} + +/* + Add shadow on hover. + + Performant box-shadow animation pattern from + http://tobiasahlin.com/blog/how-to-animate-box-shadow/ +*/ + +.shadow-hover { + cursor: pointer; + position: relative; + transition: all 0.5s cubic-bezier(0.165, 0.84, 0.44, 1); +} + +.shadow-hover::after { + content: ''; + box-shadow: 0px 0px 16px 2px rgba(0, 0, 0, .2); + border-radius: inherit; + opacity: 0; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: -1; + transition: opacity 0.5s cubic-bezier(0.165, 0.84, 0.44, 1); +} + +.shadow-hover:hover::after, +.shadow-hover:focus::after { + opacity: 1; +} + +/* Combine with classes in skins and skins-pseudo for + * many different transition possibilities. */ + +.bg-animate, +.bg-animate:hover, +.bg-animate:focus { + transition: background-color .15s ease-in-out; +} + +/* + + Z-INDEX + + Base + z = z-index + + Modifiers + -0 = literal value 0 + -1 = literal value 1 + -2 = literal value 2 + -3 = literal value 3 + -4 = literal value 4 + -5 = literal value 5 + -999 = literal value 999 + -9999 = literal value 9999 + + -max = largest accepted z-index value as integer + + -inherit = string value inherit + -initial = string value initial + -unset = string value unset + + MDN: https://developer.mozilla.org/en/docs/Web/CSS/z-index + Spec: http://www.w3.org/TR/CSS2/zindex.html + Articles: + https://philipwalton.com/articles/what-no-one-told-you-about-z-index/ + + Tips on extending: + There might be a time worth using negative z-index values. + Or if you are using tachyons with another project, you might need to + adjust these values to suit your needs. + +*/ + +.z-0 { z-index: 0; } + +.z-1 { z-index: 1; } + +.z-2 { z-index: 2; } + +.z-3 { z-index: 3; } + +.z-4 { z-index: 4; } + +.z-5 { z-index: 5; } + +.z-999 { z-index: 999; } + +.z-9999 { z-index: 9999; } + +.z-max { + z-index: 2147483647; +} + +.z-inherit { z-index: inherit; } + +.z-initial { z-index: auto; z-index: initial; } + +.z-unset { z-index: unset; } + +/* + + NESTED + Tachyons module for styling nested elements + that are generated by a cms. + +*/ + +.nested-copy-line-height p, +.nested-copy-line-height ul, +.nested-copy-line-height ol { + line-height: 1.5; +} + +.nested-headline-line-height h1, +.nested-headline-line-height h2, +.nested-headline-line-height h3, +.nested-headline-line-height h4, +.nested-headline-line-height h5, +.nested-headline-line-height h6 { + line-height: 1.25; +} + +.nested-list-reset ul, +.nested-list-reset ol { + padding-left: 0; + margin-left: 0; + list-style-type: none; +} + +.nested-copy-indent p+p { + text-indent: 1em; + margin-top: 0; + margin-bottom: 0; +} + +.nested-copy-separator p+p { + margin-top: 1.5em; +} + +.nested-img img { + width: 100%; + max-width: 100%; + display: block; +} + +.nested-links a { + color: #357edd; + transition: color .15s ease-in; +} + +.nested-links a:hover, +.nested-links a:focus { + color: #96ccff; + transition: color .15s ease-in; +} + +/* + + STYLES + + Add custom styles here. + +*/ + +/* Variables */ + +/* Importing here will allow you to override any variables in the modules */ + +/* + + Tachyons + COLOR VARIABLES + + Grayscale + - Solids + - Transparencies + Colors + +*/ + +/* + + CUSTOM MEDIA QUERIES + + Media query values can be changed to fit your own content. + There are no magic bullets when it comes to media query width values. + They should be declared in em units - and they should be set to meet + the needs of your content. You can also add additional media queries, + or remove some of the existing ones. + + These media queries can be referenced like so: + + @media (--breakpoint-not-small) { + .medium-and-larger-specific-style { + background-color: red; + } + } + + @media (--breakpoint-medium) { + .medium-screen-specific-style { + background-color: red; + } + } + + @media (--breakpoint-large) { + .large-and-larger-screen-specific-style { + background-color: red; + } + } + +*/ + +/* Media Queries */ + +/* Debugging */ + +/* @import 'tachyons/src/_debug-children'; +@import 'tachyons/src/_debug-grid'; */ + +/* Uncomment out the line below to help debug layout issues */ + +/* @import 'tachyons/src/_debug'; */ + +pre, .pre { + overflow-x: auto; + overflow-y: hidden; + overflow: scroll; +} + +pre code { + display: block; + padding: 1.5em 1.5em; + white-space: pre; + font-size: .875rem; + line-height: 2; + +} + +pre { + background-color: #222; + color: #ddd; + white-space: pre; + + -webkit-hyphens: none; + + -ms-hyphens: none; + + hyphens: none; + position: relative; +} + +/* pagination.html: https://github.com/spf13/hugo/blob/master/tpl/tplimpl/template_embedded.go#L117 */ + +.pagination { + margin: 3rem 0; +} + +.pagination li { + display: inline-block; + margin-right: .375rem; + font-size: .875rem; + margin-bottom: 2.5em; +} + +.pagination li a { + padding: .5rem .625rem; + background-color: white; + color: #333; + border: 1px solid #ddd; + border-radius: 3px; + text-decoration: none; +} + +.pagination li.disabled { + display: none; +} + +.pagination li.active a:link, +.pagination li.active a:active, +.pagination li.active a:visited { + background-color: #ddd; +} + +#TableOfContents ul li { + margin-bottom: 1em; +} + +.facebook, .twitter, .instagram, .youtube, .github, .gitlab, .keybase, .linkedin, .medium, .mastodon, .slack, .stackoverflow { + fill: #BABABA; +} + +.new-window { + opacity: 0; + display: inline-block; + vertical-align: top; +} + +.link-transition:hover .new-window{ + opacity: 1; +} + +.facebook:hover { + fill: #3b5998; +} + +.twitter:hover { + fill: #1da1f2; +} + +.instagram:hover { + fill: #e1306c; +} + +.youtube:hover { + fill: #cd201f; +} + +.github:hover { + fill: #6cc644; +} + +.gitlab:hover { + fill: #FC6D26; +} + +.keybase:hover { + fill: #3d76ff; +} + +.linkedin:hover { + fill: #0077b5 +} + +.medium:hover { + fill: #0077b5 +} + +.mastodon:hover { + fill: #3088d4; +} + +.slack:hover { + fill: #E01E5A; +} + +.stackoverflow:hover { + fill: #f48024; +} + +/* Put your custom styles here and run `npm start` from the "src" directory on */ + +#TableOfContents ul li { + margin-bottom: 1em; +} + +.lh-copy blockquote { + display: block; + font-size: .875em; + margin-left: 2rem; + margin-top: 2rem; + margin-bottom: 2rem; + border-left: 4px solid #ccc; + padding-left: 1rem; + +} + +a{ + word-wrap: break-word; +} diff --git a/public/dist/css/app.e6e75cdafe2e909dacfabeb26857f994.css b/public/dist/css/app.e6e75cdafe2e909dacfabeb26857f994.css new file mode 100644 index 00000000..51a05bcd --- /dev/null +++ b/public/dist/css/app.e6e75cdafe2e909dacfabeb26857f994.css @@ -0,0 +1,5872 @@ +/*! TACHYONS v4.9.1 | http://tachyons.io */ + +/* + * + * ________ ______ + * ___ __/_____ _________ /______ ______________________ + * __ / _ __ `/ ___/_ __ \_ / / / __ \_ __ \_ ___/ + * _ / / /_/ // /__ _ / / / /_/ // /_/ / / / /(__ ) + * /_/ \__,_/ \___/ /_/ /_/_\__, / \____//_/ /_//____/ + * /____/ + * + * TABLE OF CONTENTS + * + * 1. External Library Includes + * - Normalize.css | http://normalize.css.github.io + * 2. Tachyons Modules + * 3. Variables + * - Media Queries + * - Colors + * 4. Debugging + * - Debug all + * - Debug children + * + */ + +/* External Library Includes */ + +/*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */ + +/* Document + ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in iOS. + */ + +html { + line-height: 1.15; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/* Sections + ========================================================================== */ + +/** + * Remove the margin in all browsers. + */ + +body { + margin: 0; +} + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/* Grouping content + ========================================================================== */ + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + +hr { + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +pre { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Remove the gray background on active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * 1. Remove the bottom border in Chrome 57- + * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. + */ + +abbr[title] { + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + text-decoration: underline dotted; /* 2 */ +} + +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + +b, +strong { + font-weight: bolder; +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +code, +kbd, +samp { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/** + * Add the correct font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` elements from affecting the line height in + * all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove the border on images inside links in IE 10. + */ + +img { + border-style: none; +} + +/* Forms + ========================================================================== */ + +/** + * 1. Change the font styles in all browsers. + * 2. Remove the margin in Firefox and Safari. + */ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ +} + +/** + * Show the overflow in IE. + * 1. Show the overflow in Edge. + */ + +button, +input { /* 1 */ + overflow: visible; +} + +/** + * Remove the inheritance of text transform in Edge, Firefox, and IE. + * 1. Remove the inheritance of text transform in Firefox. + */ + +button, +select { /* 1 */ + text-transform: none; +} + +/** + * Correct the inability to style clickable types in iOS and Safari. + */ + +button, +[type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} + +/** + * Remove the inner border and padding in Firefox. + */ + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus styles unset by the previous rule. + */ + +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; +} + +/** + * Correct the padding in Firefox. + */ + +fieldset { + padding: 0.35em 0.75em 0.625em; +} + +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + +legend { + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ +} + +/** + * Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + +progress { + vertical-align: baseline; +} + +/** + * Remove the default vertical scrollbar in IE 10+. + */ + +textarea { + overflow: auto; +} + +/** + * 1. Add the correct box sizing in IE 10. + * 2. Remove the padding in IE 10. + */ + +[type="checkbox"], +[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type="search"] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Remove the inner padding in Chrome and Safari on macOS. + */ + +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + +::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} + +/* Interactive + ========================================================================== */ + +/* + * Add the correct display in Edge, IE 10+, and Firefox. + */ + +details { + display: block; +} + +/* + * Add the correct display in all browsers. + */ + +summary { + display: list-item; +} + +/* Misc + ========================================================================== */ + +/** + * Add the correct display in IE 10+. + */ + +template { + display: none; +} + +/** + * Add the correct display in IE 10. + */ + +[hidden] { + display: none; +} + +/* Modules */ + +/* + + BOX SIZING + +*/ + +html, +body, +div, +article, +aside, +section, +main, +nav, +footer, +header, +form, +fieldset, +legend, +pre, +code, +a, +h1,h2,h3,h4,h5,h6, +p, +ul, +ol, +li, +dl, +dt, +dd, +blockquote, +figcaption, +figure, +textarea, +table, +td, +th, +tr, +input[type="email"], +input[type="number"], +input[type="password"], +input[type="tel"], +input[type="text"], +input[type="url"], +.border-box { + box-sizing: border-box; +} + +/* + + ASPECT RATIOS + +*/ + +/* This is for fluid media that is embedded from third party sites like youtube, vimeo etc. + * Wrap the outer element in aspect-ratio and then extend it with the desired ratio i.e + * Make sure there are no height and width attributes on the embedded media. + * Adapted from: https://github.com/suitcss/components-flex-embed + * + * Example: + * + *
+ * + *
+ * + * */ + +.aspect-ratio { + height: 0; + position: relative; +} + +.aspect-ratio--16x9 { padding-bottom: 56.25%; } + +.aspect-ratio--9x16 { padding-bottom: 177.77%; } + +.aspect-ratio--4x3 { padding-bottom: 75%; } + +.aspect-ratio--3x4 { padding-bottom: 133.33%; } + +.aspect-ratio--6x4 { padding-bottom: 66.6%; } + +.aspect-ratio--4x6 { padding-bottom: 150%; } + +.aspect-ratio--8x5 { padding-bottom: 62.5%; } + +.aspect-ratio--5x8 { padding-bottom: 160%; } + +.aspect-ratio--7x5 { padding-bottom: 71.42%; } + +.aspect-ratio--5x7 { padding-bottom: 140%; } + +.aspect-ratio--1x1 { padding-bottom: 100%; } + +.aspect-ratio--object { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100; +} + +@media screen and (min-width: 30em){ + .aspect-ratio-ns { + height: 0; + position: relative; + } + .aspect-ratio--16x9-ns { padding-bottom: 56.25%; } + .aspect-ratio--9x16-ns { padding-bottom: 177.77%; } + .aspect-ratio--4x3-ns { padding-bottom: 75%; } + .aspect-ratio--3x4-ns { padding-bottom: 133.33%; } + .aspect-ratio--6x4-ns { padding-bottom: 66.6%; } + .aspect-ratio--4x6-ns { padding-bottom: 150%; } + .aspect-ratio--8x5-ns { padding-bottom: 62.5%; } + .aspect-ratio--5x8-ns { padding-bottom: 160%; } + .aspect-ratio--7x5-ns { padding-bottom: 71.42%; } + .aspect-ratio--5x7-ns { padding-bottom: 140%; } + .aspect-ratio--1x1-ns { padding-bottom: 100%; } + .aspect-ratio--object-ns { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100; + } +} + +@media screen and (min-width: 30em) and (max-width: 60em){ + .aspect-ratio-m { + height: 0; + position: relative; + } + .aspect-ratio--16x9-m { padding-bottom: 56.25%; } + .aspect-ratio--9x16-m { padding-bottom: 177.77%; } + .aspect-ratio--4x3-m { padding-bottom: 75%; } + .aspect-ratio--3x4-m { padding-bottom: 133.33%; } + .aspect-ratio--6x4-m { padding-bottom: 66.6%; } + .aspect-ratio--4x6-m { padding-bottom: 150%; } + .aspect-ratio--8x5-m { padding-bottom: 62.5%; } + .aspect-ratio--5x8-m { padding-bottom: 160%; } + .aspect-ratio--7x5-m { padding-bottom: 71.42%; } + .aspect-ratio--5x7-m { padding-bottom: 140%; } + .aspect-ratio--1x1-m { padding-bottom: 100%; } + .aspect-ratio--object-m { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100; + } +} + +@media screen and (min-width: 60em){ + .aspect-ratio-l { + height: 0; + position: relative; + } + .aspect-ratio--16x9-l { padding-bottom: 56.25%; } + .aspect-ratio--9x16-l { padding-bottom: 177.77%; } + .aspect-ratio--4x3-l { padding-bottom: 75%; } + .aspect-ratio--3x4-l { padding-bottom: 133.33%; } + .aspect-ratio--6x4-l { padding-bottom: 66.6%; } + .aspect-ratio--4x6-l { padding-bottom: 150%; } + .aspect-ratio--8x5-l { padding-bottom: 62.5%; } + .aspect-ratio--5x8-l { padding-bottom: 160%; } + .aspect-ratio--7x5-l { padding-bottom: 71.42%; } + .aspect-ratio--5x7-l { padding-bottom: 140%; } + .aspect-ratio--1x1-l { padding-bottom: 100%; } + .aspect-ratio--object-l { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100; + } +} + +/* + + IMAGES + Docs: http://tachyons.io/docs/elements/images/ + +*/ + +/* Responsive images! */ + +img { max-width: 100%; } + +/* + + BACKGROUND SIZE + Docs: http://tachyons.io/docs/themes/background-size/ + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +/* + Often used in combination with background image set as an inline style + on an html element. +*/ + +.cover { background-size: cover!important; } + +.contain { background-size: contain!important; } + +@media screen and (min-width: 30em) { + .cover-ns { background-size: cover!important; } + .contain-ns { background-size: contain!important; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .cover-m { background-size: cover!important; } + .contain-m { background-size: contain!important; } +} + +@media screen and (min-width: 60em) { + .cover-l { background-size: cover!important; } + .contain-l { background-size: contain!important; } +} + +/* + + BACKGROUND POSITION + + Base: + bg = background + + Modifiers: + -center = center center + -top = top center + -right = center right + -bottom = bottom center + -left = center left + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + + */ + +.bg-center { + background-repeat: no-repeat; + background-position: center center; +} + +.bg-top { + background-repeat: no-repeat; + background-position: top center; +} + +.bg-right { + background-repeat: no-repeat; + background-position: center right; +} + +.bg-bottom { + background-repeat: no-repeat; + background-position: bottom center; +} + +.bg-left { + background-repeat: no-repeat; + background-position: center left; +} + +@media screen and (min-width: 30em) { + .bg-center-ns { + background-repeat: no-repeat; + background-position: center center; + } + + .bg-top-ns { + background-repeat: no-repeat; + background-position: top center; + } + + .bg-right-ns { + background-repeat: no-repeat; + background-position: center right; + } + + .bg-bottom-ns { + background-repeat: no-repeat; + background-position: bottom center; + } + + .bg-left-ns { + background-repeat: no-repeat; + background-position: center left; + } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .bg-center-m { + background-repeat: no-repeat; + background-position: center center; + } + + .bg-top-m { + background-repeat: no-repeat; + background-position: top center; + } + + .bg-right-m { + background-repeat: no-repeat; + background-position: center right; + } + + .bg-bottom-m { + background-repeat: no-repeat; + background-position: bottom center; + } + + .bg-left-m { + background-repeat: no-repeat; + background-position: center left; + } +} + +@media screen and (min-width: 60em) { + .bg-center-l { + background-repeat: no-repeat; + background-position: center center; + } + + .bg-top-l { + background-repeat: no-repeat; + background-position: top center; + } + + .bg-right-l { + background-repeat: no-repeat; + background-position: center right; + } + + .bg-bottom-l { + background-repeat: no-repeat; + background-position: bottom center; + } + + .bg-left-l { + background-repeat: no-repeat; + background-position: center left; + } +} + +/* + + OUTLINES + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.outline { outline: 1px solid; } + +.outline-transparent { outline: 1px solid transparent; } + +.outline-0 { outline: 0; } + +@media screen and (min-width: 30em) { + .outline-ns { outline: 1px solid; } + .outline-transparent-ns { outline: 1px solid transparent; } + .outline-0-ns { outline: 0; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .outline-m { outline: 1px solid; } + .outline-transparent-m { outline: 1px solid transparent; } + .outline-0-m { outline: 0; } +} + +@media screen and (min-width: 60em) { + .outline-l { outline: 1px solid; } + .outline-transparent-l { outline: 1px solid transparent; } + .outline-0-l { outline: 0; } +} + +/* + + BORDERS + Docs: http://tachyons.io/docs/themes/borders/ + + Base: + b = border + + Modifiers: + a = all + t = top + r = right + b = bottom + l = left + n = none + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.ba { border-style: solid; border-width: 1px; } + +.bt { border-top-style: solid; border-top-width: 1px; } + +.br { border-right-style: solid; border-right-width: 1px; } + +.bb { border-bottom-style: solid; border-bottom-width: 1px; } + +.bl { border-left-style: solid; border-left-width: 1px; } + +.bn { border-style: none; border-width: 0; } + +@media screen and (min-width: 30em) { + .ba-ns { border-style: solid; border-width: 1px; } + .bt-ns { border-top-style: solid; border-top-width: 1px; } + .br-ns { border-right-style: solid; border-right-width: 1px; } + .bb-ns { border-bottom-style: solid; border-bottom-width: 1px; } + .bl-ns { border-left-style: solid; border-left-width: 1px; } + .bn-ns { border-style: none; border-width: 0; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .ba-m { border-style: solid; border-width: 1px; } + .bt-m { border-top-style: solid; border-top-width: 1px; } + .br-m { border-right-style: solid; border-right-width: 1px; } + .bb-m { border-bottom-style: solid; border-bottom-width: 1px; } + .bl-m { border-left-style: solid; border-left-width: 1px; } + .bn-m { border-style: none; border-width: 0; } +} + +@media screen and (min-width: 60em) { + .ba-l { border-style: solid; border-width: 1px; } + .bt-l { border-top-style: solid; border-top-width: 1px; } + .br-l { border-right-style: solid; border-right-width: 1px; } + .bb-l { border-bottom-style: solid; border-bottom-width: 1px; } + .bl-l { border-left-style: solid; border-left-width: 1px; } + .bn-l { border-style: none; border-width: 0; } +} + +/* + + BORDER COLORS + Docs: http://tachyons.io/docs/themes/borders/ + + Border colors can be used to extend the base + border classes ba,bt,bb,br,bl found in the _borders.css file. + + The base border class by default will set the color of the border + to that of the current text color. These classes are for the cases + where you desire for the text and border colors to be different. + + Base: + b = border + + Modifiers: + --color-name = each color variable name is also a border color name + +*/ + +.b--black { border-color: #000; } + +.b--near-black { border-color: #111; } + +.b--dark-gray { border-color: #333; } + +.b--mid-gray { border-color: #555; } + +.b--gray { border-color: #777; } + +.b--silver { border-color: #999; } + +.b--light-silver { border-color: #aaa; } + +.b--moon-gray { border-color: #ccc; } + +.b--light-gray { border-color: #eee; } + +.b--near-white { border-color: #f4f4f4; } + +.b--white { border-color: #fff; } + +.b--white-90 { border-color: rgba(255, 255, 255, .9); } + +.b--white-80 { border-color: rgba(255, 255, 255, .8); } + +.b--white-70 { border-color: rgba(255, 255, 255, .7); } + +.b--white-60 { border-color: rgba(255, 255, 255, .6); } + +.b--white-50 { border-color: rgba(255, 255, 255, .5); } + +.b--white-40 { border-color: rgba(255, 255, 255, .4); } + +.b--white-30 { border-color: rgba(255, 255, 255, .3); } + +.b--white-20 { border-color: rgba(255, 255, 255, .2); } + +.b--white-10 { border-color: rgba(255, 255, 255, .1); } + +.b--white-05 { border-color: rgba(255, 255, 255, .05); } + +.b--white-025 { border-color: rgba(255, 255, 255, .025); } + +.b--white-0125 { border-color: rgba(255, 255, 255, .0125); } + +.b--black-90 { border-color: rgba(0, 0, 0, .9); } + +.b--black-80 { border-color: rgba(0, 0, 0, .8); } + +.b--black-70 { border-color: rgba(0, 0, 0, .7); } + +.b--black-60 { border-color: rgba(0, 0, 0, .6); } + +.b--black-50 { border-color: rgba(0, 0, 0, .5); } + +.b--black-40 { border-color: rgba(0, 0, 0, .4); } + +.b--black-30 { border-color: rgba(0, 0, 0, .3); } + +.b--black-20 { border-color: rgba(0, 0, 0, .2); } + +.b--black-10 { border-color: rgba(0, 0, 0, .1); } + +.b--black-05 { border-color: rgba(0, 0, 0, .05); } + +.b--black-025 { border-color: rgba(0, 0, 0, .025); } + +.b--black-0125 { border-color: rgba(0, 0, 0, .0125); } + +.b--dark-red { border-color: #e7040f; } + +.b--red { border-color: #ff4136; } + +.b--light-red { border-color: #ff725c; } + +.b--orange { border-color: #ff6300; } + +.b--gold { border-color: #ffb700; } + +.b--yellow { border-color: #ffd700; } + +.b--light-yellow { border-color: #fbf1a9; } + +.b--purple { border-color: #5e2ca5; } + +.b--light-purple { border-color: #a463f2; } + +.b--dark-pink { border-color: #d5008f; } + +.b--hot-pink { border-color: #ff41b4; } + +.b--pink { border-color: #ff80cc; } + +.b--light-pink { border-color: #ffa3d7; } + +.b--dark-green { border-color: #137752; } + +.b--green { border-color: #19a974; } + +.b--light-green { border-color: #9eebcf; } + +.b--navy { border-color: #001b44; } + +.b--dark-blue { border-color: #00449e; } + +.b--blue { border-color: #357edd; } + +.b--light-blue { border-color: #96ccff; } + +.b--lightest-blue { border-color: #cdecff; } + +.b--washed-blue { border-color: #f6fffe; } + +.b--washed-green { border-color: #e8fdf5; } + +.b--washed-yellow { border-color: #fffceb; } + +.b--washed-red { border-color: #ffdfdf; } + +.b--transparent { border-color: transparent; } + +.b--inherit { border-color: inherit; } + +/* + + BORDER RADIUS + Docs: http://tachyons.io/docs/themes/border-radius/ + + Base: + br = border-radius + + Modifiers: + 0 = 0/none + 1 = 1st step in scale + 2 = 2nd step in scale + 3 = 3rd step in scale + 4 = 4th step in scale + + Literal values: + -100 = 100% + -pill = 9999px + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.br0 { border-radius: 0; } + +.br1 { border-radius: .125rem; } + +.br2 { border-radius: .25rem; } + +.br3 { border-radius: .5rem; } + +.br4 { border-radius: 1rem; } + +.br-100 { border-radius: 100%; } + +.br-pill { border-radius: 9999px; } + +.br--bottom { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + +.br--top { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + +.br--right { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + +.br--left { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + +@media screen and (min-width: 30em) { + .br0-ns { border-radius: 0; } + .br1-ns { border-radius: .125rem; } + .br2-ns { border-radius: .25rem; } + .br3-ns { border-radius: .5rem; } + .br4-ns { border-radius: 1rem; } + .br-100-ns { border-radius: 100%; } + .br-pill-ns { border-radius: 9999px; } + .br--bottom-ns { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + .br--top-ns { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + .br--right-ns { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .br--left-ns { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .br0-m { border-radius: 0; } + .br1-m { border-radius: .125rem; } + .br2-m { border-radius: .25rem; } + .br3-m { border-radius: .5rem; } + .br4-m { border-radius: 1rem; } + .br-100-m { border-radius: 100%; } + .br-pill-m { border-radius: 9999px; } + .br--bottom-m { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + .br--top-m { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + .br--right-m { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .br--left-m { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } +} + +@media screen and (min-width: 60em) { + .br0-l { border-radius: 0; } + .br1-l { border-radius: .125rem; } + .br2-l { border-radius: .25rem; } + .br3-l { border-radius: .5rem; } + .br4-l { border-radius: 1rem; } + .br-100-l { border-radius: 100%; } + .br-pill-l { border-radius: 9999px; } + .br--bottom-l { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + .br--top-l { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + .br--right-l { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .br--left-l { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } +} + +/* + + BORDER STYLES + Docs: http://tachyons.io/docs/themes/borders/ + + Depends on base border module in _borders.css + + Base: + b = border-style + + Modifiers: + --none = none + --dotted = dotted + --dashed = dashed + --solid = solid + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + + */ + +.b--dotted { border-style: dotted; } + +.b--dashed { border-style: dashed; } + +.b--solid { border-style: solid; } + +.b--none { border-style: none; } + +@media screen and (min-width: 30em) { + .b--dotted-ns { border-style: dotted; } + .b--dashed-ns { border-style: dashed; } + .b--solid-ns { border-style: solid; } + .b--none-ns { border-style: none; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .b--dotted-m { border-style: dotted; } + .b--dashed-m { border-style: dashed; } + .b--solid-m { border-style: solid; } + .b--none-m { border-style: none; } +} + +@media screen and (min-width: 60em) { + .b--dotted-l { border-style: dotted; } + .b--dashed-l { border-style: dashed; } + .b--solid-l { border-style: solid; } + .b--none-l { border-style: none; } +} + +/* + + BORDER WIDTHS + Docs: http://tachyons.io/docs/themes/borders/ + + Base: + bw = border-width + + Modifiers: + 0 = 0 width border + 1 = 1st step in border-width scale + 2 = 2nd step in border-width scale + 3 = 3rd step in border-width scale + 4 = 4th step in border-width scale + 5 = 5th step in border-width scale + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.bw0 { border-width: 0; } + +.bw1 { border-width: .125rem; } + +.bw2 { border-width: .25rem; } + +.bw3 { border-width: .5rem; } + +.bw4 { border-width: 1rem; } + +.bw5 { border-width: 2rem; } + +/* Resets */ + +.bt-0 { border-top-width: 0; } + +.br-0 { border-right-width: 0; } + +.bb-0 { border-bottom-width: 0; } + +.bl-0 { border-left-width: 0; } + +@media screen and (min-width: 30em) { + .bw0-ns { border-width: 0; } + .bw1-ns { border-width: .125rem; } + .bw2-ns { border-width: .25rem; } + .bw3-ns { border-width: .5rem; } + .bw4-ns { border-width: 1rem; } + .bw5-ns { border-width: 2rem; } + .bt-0-ns { border-top-width: 0; } + .br-0-ns { border-right-width: 0; } + .bb-0-ns { border-bottom-width: 0; } + .bl-0-ns { border-left-width: 0; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .bw0-m { border-width: 0; } + .bw1-m { border-width: .125rem; } + .bw2-m { border-width: .25rem; } + .bw3-m { border-width: .5rem; } + .bw4-m { border-width: 1rem; } + .bw5-m { border-width: 2rem; } + .bt-0-m { border-top-width: 0; } + .br-0-m { border-right-width: 0; } + .bb-0-m { border-bottom-width: 0; } + .bl-0-m { border-left-width: 0; } +} + +@media screen and (min-width: 60em) { + .bw0-l { border-width: 0; } + .bw1-l { border-width: .125rem; } + .bw2-l { border-width: .25rem; } + .bw3-l { border-width: .5rem; } + .bw4-l { border-width: 1rem; } + .bw5-l { border-width: 2rem; } + .bt-0-l { border-top-width: 0; } + .br-0-l { border-right-width: 0; } + .bb-0-l { border-bottom-width: 0; } + .bl-0-l { border-left-width: 0; } +} + +/* + + BOX-SHADOW + Docs: http://tachyons.io/docs/themes/box-shadow/ + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + + */ + +.shadow-1 { box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, .2); } + +.shadow-2 { box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, .2); } + +.shadow-3 { box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, .2); } + +.shadow-4 { box-shadow: 2px 2px 8px 0px rgba(0, 0, 0, .2); } + +.shadow-5 { box-shadow: 4px 4px 8px 0px rgba(0, 0, 0, .2); } + +@media screen and (min-width: 30em) { + .shadow-1-ns { box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, .2); } + .shadow-2-ns { box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, .2); } + .shadow-3-ns { box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, .2); } + .shadow-4-ns { box-shadow: 2px 2px 8px 0px rgba(0, 0, 0, .2); } + .shadow-5-ns { box-shadow: 4px 4px 8px 0px rgba(0, 0, 0, .2); } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .shadow-1-m { box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, .2); } + .shadow-2-m { box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, .2); } + .shadow-3-m { box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, .2); } + .shadow-4-m { box-shadow: 2px 2px 8px 0px rgba(0, 0, 0, .2); } + .shadow-5-m { box-shadow: 4px 4px 8px 0px rgba(0, 0, 0, .2); } +} + +@media screen and (min-width: 60em) { + .shadow-1-l { box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, .2); } + .shadow-2-l { box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, .2); } + .shadow-3-l { box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, .2); } + .shadow-4-l { box-shadow: 2px 2px 8px 0px rgba(0, 0, 0, .2); } + .shadow-5-l { box-shadow: 4px 4px 8px 0px rgba(0, 0, 0, .2); } +} + +/* + + CODE + +*/ + +.pre { + overflow-x: auto; + overflow-y: hidden; + overflow: scroll; +} + +/* + + COORDINATES + Docs: http://tachyons.io/docs/layout/position/ + + Use in combination with the position module. + + Base: + top + bottom + right + left + + Modifiers: + -0 = literal value 0 + -1 = literal value 1 + -2 = literal value 2 + --1 = literal value -1 + --2 = literal value -2 + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.top-0 { top: 0; } + +.right-0 { right: 0; } + +.bottom-0 { bottom: 0; } + +.left-0 { left: 0; } + +.top-1 { top: 1rem; } + +.right-1 { right: 1rem; } + +.bottom-1 { bottom: 1rem; } + +.left-1 { left: 1rem; } + +.top-2 { top: 2rem; } + +.right-2 { right: 2rem; } + +.bottom-2 { bottom: 2rem; } + +.left-2 { left: 2rem; } + +.top--1 { top: -1rem; } + +.right--1 { right: -1rem; } + +.bottom--1 { bottom: -1rem; } + +.left--1 { left: -1rem; } + +.top--2 { top: -2rem; } + +.right--2 { right: -2rem; } + +.bottom--2 { bottom: -2rem; } + +.left--2 { left: -2rem; } + +.absolute--fill { + top: 0; + right: 0; + bottom: 0; + left: 0; +} + +@media screen and (min-width: 30em) { + .top-0-ns { top: 0; } + .left-0-ns { left: 0; } + .right-0-ns { right: 0; } + .bottom-0-ns { bottom: 0; } + .top-1-ns { top: 1rem; } + .left-1-ns { left: 1rem; } + .right-1-ns { right: 1rem; } + .bottom-1-ns { bottom: 1rem; } + .top-2-ns { top: 2rem; } + .left-2-ns { left: 2rem; } + .right-2-ns { right: 2rem; } + .bottom-2-ns { bottom: 2rem; } + .top--1-ns { top: -1rem; } + .right--1-ns { right: -1rem; } + .bottom--1-ns { bottom: -1rem; } + .left--1-ns { left: -1rem; } + .top--2-ns { top: -2rem; } + .right--2-ns { right: -2rem; } + .bottom--2-ns { bottom: -2rem; } + .left--2-ns { left: -2rem; } + .absolute--fill-ns { + top: 0; + right: 0; + bottom: 0; + left: 0; + } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .top-0-m { top: 0; } + .left-0-m { left: 0; } + .right-0-m { right: 0; } + .bottom-0-m { bottom: 0; } + .top-1-m { top: 1rem; } + .left-1-m { left: 1rem; } + .right-1-m { right: 1rem; } + .bottom-1-m { bottom: 1rem; } + .top-2-m { top: 2rem; } + .left-2-m { left: 2rem; } + .right-2-m { right: 2rem; } + .bottom-2-m { bottom: 2rem; } + .top--1-m { top: -1rem; } + .right--1-m { right: -1rem; } + .bottom--1-m { bottom: -1rem; } + .left--1-m { left: -1rem; } + .top--2-m { top: -2rem; } + .right--2-m { right: -2rem; } + .bottom--2-m { bottom: -2rem; } + .left--2-m { left: -2rem; } + .absolute--fill-m { + top: 0; + right: 0; + bottom: 0; + left: 0; + } +} + +@media screen and (min-width: 60em) { + .top-0-l { top: 0; } + .left-0-l { left: 0; } + .right-0-l { right: 0; } + .bottom-0-l { bottom: 0; } + .top-1-l { top: 1rem; } + .left-1-l { left: 1rem; } + .right-1-l { right: 1rem; } + .bottom-1-l { bottom: 1rem; } + .top-2-l { top: 2rem; } + .left-2-l { left: 2rem; } + .right-2-l { right: 2rem; } + .bottom-2-l { bottom: 2rem; } + .top--1-l { top: -1rem; } + .right--1-l { right: -1rem; } + .bottom--1-l { bottom: -1rem; } + .left--1-l { left: -1rem; } + .top--2-l { top: -2rem; } + .right--2-l { right: -2rem; } + .bottom--2-l { bottom: -2rem; } + .left--2-l { left: -2rem; } + .absolute--fill-l { + top: 0; + right: 0; + bottom: 0; + left: 0; + } +} + +/* + + CLEARFIX + http://tachyons.io/docs/layout/clearfix/ + +*/ + +/* Nicolas Gallaghers Clearfix solution + Ref: http://nicolasgallagher.com/micro-clearfix-hack/ */ + +.cf:before, +.cf:after { content: " "; display: table; } + +.cf:after { clear: both; } + +.cf { *zoom: 1; } + +.cl { clear: left; } + +.cr { clear: right; } + +.cb { clear: both; } + +.cn { clear: none; } + +@media screen and (min-width: 30em) { + .cl-ns { clear: left; } + .cr-ns { clear: right; } + .cb-ns { clear: both; } + .cn-ns { clear: none; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .cl-m { clear: left; } + .cr-m { clear: right; } + .cb-m { clear: both; } + .cn-m { clear: none; } +} + +@media screen and (min-width: 60em) { + .cl-l { clear: left; } + .cr-l { clear: right; } + .cb-l { clear: both; } + .cn-l { clear: none; } +} + +/* + + DISPLAY + Docs: http://tachyons.io/docs/layout/display + + Base: + d = display + + Modifiers: + n = none + b = block + ib = inline-block + it = inline-table + t = table + tc = table-cell + t-row = table-row + t-columm = table-column + t-column-group = table-column-group + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.dn { display: none; } + +.di { display: inline; } + +.db { display: block; } + +.dib { display: inline-block; } + +.dit { display: inline-table; } + +.dt { display: table; } + +.dtc { display: table-cell; } + +.dt-row { display: table-row; } + +.dt-row-group { display: table-row-group; } + +.dt-column { display: table-column; } + +.dt-column-group { display: table-column-group; } + +/* + This will set table to full width and then + all cells will be equal width +*/ + +.dt--fixed { + table-layout: fixed; + width: 100%; +} + +@media screen and (min-width: 30em) { + .dn-ns { display: none; } + .di-ns { display: inline; } + .db-ns { display: block; } + .dib-ns { display: inline-block; } + .dit-ns { display: inline-table; } + .dt-ns { display: table; } + .dtc-ns { display: table-cell; } + .dt-row-ns { display: table-row; } + .dt-row-group-ns { display: table-row-group; } + .dt-column-ns { display: table-column; } + .dt-column-group-ns { display: table-column-group; } + + .dt--fixed-ns { + table-layout: fixed; + width: 100%; + } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .dn-m { display: none; } + .di-m { display: inline; } + .db-m { display: block; } + .dib-m { display: inline-block; } + .dit-m { display: inline-table; } + .dt-m { display: table; } + .dtc-m { display: table-cell; } + .dt-row-m { display: table-row; } + .dt-row-group-m { display: table-row-group; } + .dt-column-m { display: table-column; } + .dt-column-group-m { display: table-column-group; } + + .dt--fixed-m { + table-layout: fixed; + width: 100%; + } +} + +@media screen and (min-width: 60em) { + .dn-l { display: none; } + .di-l { display: inline; } + .db-l { display: block; } + .dib-l { display: inline-block; } + .dit-l { display: inline-table; } + .dt-l { display: table; } + .dtc-l { display: table-cell; } + .dt-row-l { display: table-row; } + .dt-row-group-l { display: table-row-group; } + .dt-column-l { display: table-column; } + .dt-column-group-l { display: table-column-group; } + + .dt--fixed-l { + table-layout: fixed; + width: 100%; + } +} + +/* + + FLEXBOX + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.flex { display: -webkit-box; display: -ms-flexbox; display: flex; } + +.inline-flex { display: -webkit-inline-box; display: -ms-inline-flexbox; display: inline-flex; } + +/* 1. Fix for Chrome 44 bug. + * https://code.google.com/p/chromium/issues/detail?id=506893 */ + +.flex-auto { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + min-width: 0; /* 1 */ + min-height: 0; /* 1 */ +} + +.flex-none { -webkit-box-flex: 0; -ms-flex: none; flex: none; } + +.flex-column { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } + +.flex-row { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; } + +.flex-wrap { -ms-flex-wrap: wrap; flex-wrap: wrap; } + +.flex-nowrap { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } + +.flex-wrap-reverse { -ms-flex-wrap: wrap-reverse; flex-wrap: wrap-reverse; } + +.flex-column-reverse { -webkit-box-orient: vertical; -webkit-box-direction: reverse; -ms-flex-direction: column-reverse; flex-direction: column-reverse; } + +.flex-row-reverse { -webkit-box-orient: horizontal; -webkit-box-direction: reverse; -ms-flex-direction: row-reverse; flex-direction: row-reverse; } + +.items-start { -webkit-box-align: start; -ms-flex-align: start; align-items: flex-start; } + +.items-end { -webkit-box-align: end; -ms-flex-align: end; align-items: flex-end; } + +.items-center { -webkit-box-align: center; -ms-flex-align: center; align-items: center; } + +.items-baseline { -webkit-box-align: baseline; -ms-flex-align: baseline; align-items: baseline; } + +.items-stretch { -webkit-box-align: stretch; -ms-flex-align: stretch; align-items: stretch; } + +.self-start { -ms-flex-item-align: start; align-self: flex-start; } + +.self-end { -ms-flex-item-align: end; align-self: flex-end; } + +.self-center { -ms-flex-item-align: center; -ms-grid-row-align: center; align-self: center; } + +.self-baseline { -ms-flex-item-align: baseline; align-self: baseline; } + +.self-stretch { -ms-flex-item-align: stretch; -ms-grid-row-align: stretch; align-self: stretch; } + +.justify-start { -webkit-box-pack: start; -ms-flex-pack: start; justify-content: flex-start; } + +.justify-end { -webkit-box-pack: end; -ms-flex-pack: end; justify-content: flex-end; } + +.justify-center { -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; } + +.justify-between { -webkit-box-pack: justify; -ms-flex-pack: justify; justify-content: space-between; } + +.justify-around { -ms-flex-pack: distribute; justify-content: space-around; } + +.content-start { -ms-flex-line-pack: start; align-content: flex-start; } + +.content-end { -ms-flex-line-pack: end; align-content: flex-end; } + +.content-center { -ms-flex-line-pack: center; align-content: center; } + +.content-between { -ms-flex-line-pack: justify; align-content: space-between; } + +.content-around { -ms-flex-line-pack: distribute; align-content: space-around; } + +.content-stretch { -ms-flex-line-pack: stretch; align-content: stretch; } + +.order-0 { -webkit-box-ordinal-group: 1; -ms-flex-order: 0; order: 0; } + +.order-1 { -webkit-box-ordinal-group: 2; -ms-flex-order: 1; order: 1; } + +.order-2 { -webkit-box-ordinal-group: 3; -ms-flex-order: 2; order: 2; } + +.order-3 { -webkit-box-ordinal-group: 4; -ms-flex-order: 3; order: 3; } + +.order-4 { -webkit-box-ordinal-group: 5; -ms-flex-order: 4; order: 4; } + +.order-5 { -webkit-box-ordinal-group: 6; -ms-flex-order: 5; order: 5; } + +.order-6 { -webkit-box-ordinal-group: 7; -ms-flex-order: 6; order: 6; } + +.order-7 { -webkit-box-ordinal-group: 8; -ms-flex-order: 7; order: 7; } + +.order-8 { -webkit-box-ordinal-group: 9; -ms-flex-order: 8; order: 8; } + +.order-last { -webkit-box-ordinal-group: 100000; -ms-flex-order: 99999; order: 99999; } + +.flex-grow-0 { -webkit-box-flex: 0; -ms-flex-positive: 0; flex-grow: 0; } + +.flex-grow-1 { -webkit-box-flex: 1; -ms-flex-positive: 1; flex-grow: 1; } + +.flex-shrink-0 { -ms-flex-negative: 0; flex-shrink: 0; } + +.flex-shrink-1 { -ms-flex-negative: 1; flex-shrink: 1; } + +@media screen and (min-width: 30em) { + .flex-ns { display: -webkit-box; display: -ms-flexbox; display: flex; } + .inline-flex-ns { display: -webkit-inline-box; display: -ms-inline-flexbox; display: inline-flex; } + .flex-auto-ns { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + min-width: 0; /* 1 */ + min-height: 0; /* 1 */ + } + .flex-none-ns { -webkit-box-flex: 0; -ms-flex: none; flex: none; } + .flex-column-ns { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } + .flex-row-ns { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; } + .flex-wrap-ns { -ms-flex-wrap: wrap; flex-wrap: wrap; } + .flex-nowrap-ns { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } + .flex-wrap-reverse-ns { -ms-flex-wrap: wrap-reverse; flex-wrap: wrap-reverse; } + .flex-column-reverse-ns { -webkit-box-orient: vertical; -webkit-box-direction: reverse; -ms-flex-direction: column-reverse; flex-direction: column-reverse; } + .flex-row-reverse-ns { -webkit-box-orient: horizontal; -webkit-box-direction: reverse; -ms-flex-direction: row-reverse; flex-direction: row-reverse; } + .items-start-ns { -webkit-box-align: start; -ms-flex-align: start; align-items: flex-start; } + .items-end-ns { -webkit-box-align: end; -ms-flex-align: end; align-items: flex-end; } + .items-center-ns { -webkit-box-align: center; -ms-flex-align: center; align-items: center; } + .items-baseline-ns { -webkit-box-align: baseline; -ms-flex-align: baseline; align-items: baseline; } + .items-stretch-ns { -webkit-box-align: stretch; -ms-flex-align: stretch; align-items: stretch; } + + .self-start-ns { -ms-flex-item-align: start; align-self: flex-start; } + .self-end-ns { -ms-flex-item-align: end; align-self: flex-end; } + .self-center-ns { -ms-flex-item-align: center; -ms-grid-row-align: center; align-self: center; } + .self-baseline-ns { -ms-flex-item-align: baseline; align-self: baseline; } + .self-stretch-ns { -ms-flex-item-align: stretch; -ms-grid-row-align: stretch; align-self: stretch; } + + .justify-start-ns { -webkit-box-pack: start; -ms-flex-pack: start; justify-content: flex-start; } + .justify-end-ns { -webkit-box-pack: end; -ms-flex-pack: end; justify-content: flex-end; } + .justify-center-ns { -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; } + .justify-between-ns { -webkit-box-pack: justify; -ms-flex-pack: justify; justify-content: space-between; } + .justify-around-ns { -ms-flex-pack: distribute; justify-content: space-around; } + + .content-start-ns { -ms-flex-line-pack: start; align-content: flex-start; } + .content-end-ns { -ms-flex-line-pack: end; align-content: flex-end; } + .content-center-ns { -ms-flex-line-pack: center; align-content: center; } + .content-between-ns { -ms-flex-line-pack: justify; align-content: space-between; } + .content-around-ns { -ms-flex-line-pack: distribute; align-content: space-around; } + .content-stretch-ns { -ms-flex-line-pack: stretch; align-content: stretch; } + + .order-0-ns { -webkit-box-ordinal-group: 1; -ms-flex-order: 0; order: 0; } + .order-1-ns { -webkit-box-ordinal-group: 2; -ms-flex-order: 1; order: 1; } + .order-2-ns { -webkit-box-ordinal-group: 3; -ms-flex-order: 2; order: 2; } + .order-3-ns { -webkit-box-ordinal-group: 4; -ms-flex-order: 3; order: 3; } + .order-4-ns { -webkit-box-ordinal-group: 5; -ms-flex-order: 4; order: 4; } + .order-5-ns { -webkit-box-ordinal-group: 6; -ms-flex-order: 5; order: 5; } + .order-6-ns { -webkit-box-ordinal-group: 7; -ms-flex-order: 6; order: 6; } + .order-7-ns { -webkit-box-ordinal-group: 8; -ms-flex-order: 7; order: 7; } + .order-8-ns { -webkit-box-ordinal-group: 9; -ms-flex-order: 8; order: 8; } + .order-last-ns { -webkit-box-ordinal-group: 100000; -ms-flex-order: 99999; order: 99999; } + + .flex-grow-0-ns { -webkit-box-flex: 0; -ms-flex-positive: 0; flex-grow: 0; } + .flex-grow-1-ns { -webkit-box-flex: 1; -ms-flex-positive: 1; flex-grow: 1; } + + .flex-shrink-0-ns { -ms-flex-negative: 0; flex-shrink: 0; } + .flex-shrink-1-ns { -ms-flex-negative: 1; flex-shrink: 1; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .flex-m { display: -webkit-box; display: -ms-flexbox; display: flex; } + .inline-flex-m { display: -webkit-inline-box; display: -ms-inline-flexbox; display: inline-flex; } + .flex-auto-m { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + min-width: 0; /* 1 */ + min-height: 0; /* 1 */ + } + .flex-none-m { -webkit-box-flex: 0; -ms-flex: none; flex: none; } + .flex-column-m { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } + .flex-row-m { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; } + .flex-wrap-m { -ms-flex-wrap: wrap; flex-wrap: wrap; } + .flex-nowrap-m { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } + .flex-wrap-reverse-m { -ms-flex-wrap: wrap-reverse; flex-wrap: wrap-reverse; } + .flex-column-reverse-m { -webkit-box-orient: vertical; -webkit-box-direction: reverse; -ms-flex-direction: column-reverse; flex-direction: column-reverse; } + .flex-row-reverse-m { -webkit-box-orient: horizontal; -webkit-box-direction: reverse; -ms-flex-direction: row-reverse; flex-direction: row-reverse; } + .items-start-m { -webkit-box-align: start; -ms-flex-align: start; align-items: flex-start; } + .items-end-m { -webkit-box-align: end; -ms-flex-align: end; align-items: flex-end; } + .items-center-m { -webkit-box-align: center; -ms-flex-align: center; align-items: center; } + .items-baseline-m { -webkit-box-align: baseline; -ms-flex-align: baseline; align-items: baseline; } + .items-stretch-m { -webkit-box-align: stretch; -ms-flex-align: stretch; align-items: stretch; } + + .self-start-m { -ms-flex-item-align: start; align-self: flex-start; } + .self-end-m { -ms-flex-item-align: end; align-self: flex-end; } + .self-center-m { -ms-flex-item-align: center; -ms-grid-row-align: center; align-self: center; } + .self-baseline-m { -ms-flex-item-align: baseline; align-self: baseline; } + .self-stretch-m { -ms-flex-item-align: stretch; -ms-grid-row-align: stretch; align-self: stretch; } + + .justify-start-m { -webkit-box-pack: start; -ms-flex-pack: start; justify-content: flex-start; } + .justify-end-m { -webkit-box-pack: end; -ms-flex-pack: end; justify-content: flex-end; } + .justify-center-m { -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; } + .justify-between-m { -webkit-box-pack: justify; -ms-flex-pack: justify; justify-content: space-between; } + .justify-around-m { -ms-flex-pack: distribute; justify-content: space-around; } + + .content-start-m { -ms-flex-line-pack: start; align-content: flex-start; } + .content-end-m { -ms-flex-line-pack: end; align-content: flex-end; } + .content-center-m { -ms-flex-line-pack: center; align-content: center; } + .content-between-m { -ms-flex-line-pack: justify; align-content: space-between; } + .content-around-m { -ms-flex-line-pack: distribute; align-content: space-around; } + .content-stretch-m { -ms-flex-line-pack: stretch; align-content: stretch; } + + .order-0-m { -webkit-box-ordinal-group: 1; -ms-flex-order: 0; order: 0; } + .order-1-m { -webkit-box-ordinal-group: 2; -ms-flex-order: 1; order: 1; } + .order-2-m { -webkit-box-ordinal-group: 3; -ms-flex-order: 2; order: 2; } + .order-3-m { -webkit-box-ordinal-group: 4; -ms-flex-order: 3; order: 3; } + .order-4-m { -webkit-box-ordinal-group: 5; -ms-flex-order: 4; order: 4; } + .order-5-m { -webkit-box-ordinal-group: 6; -ms-flex-order: 5; order: 5; } + .order-6-m { -webkit-box-ordinal-group: 7; -ms-flex-order: 6; order: 6; } + .order-7-m { -webkit-box-ordinal-group: 8; -ms-flex-order: 7; order: 7; } + .order-8-m { -webkit-box-ordinal-group: 9; -ms-flex-order: 8; order: 8; } + .order-last-m { -webkit-box-ordinal-group: 100000; -ms-flex-order: 99999; order: 99999; } + + .flex-grow-0-m { -webkit-box-flex: 0; -ms-flex-positive: 0; flex-grow: 0; } + .flex-grow-1-m { -webkit-box-flex: 1; -ms-flex-positive: 1; flex-grow: 1; } + + .flex-shrink-0-m { -ms-flex-negative: 0; flex-shrink: 0; } + .flex-shrink-1-m { -ms-flex-negative: 1; flex-shrink: 1; } +} + +@media screen and (min-width: 60em) { + .flex-l { display: -webkit-box; display: -ms-flexbox; display: flex; } + .inline-flex-l { display: -webkit-inline-box; display: -ms-inline-flexbox; display: inline-flex; } + .flex-auto-l { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + min-width: 0; /* 1 */ + min-height: 0; /* 1 */ + } + .flex-none-l { -webkit-box-flex: 0; -ms-flex: none; flex: none; } + .flex-column-l { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } + .flex-row-l { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; } + .flex-wrap-l { -ms-flex-wrap: wrap; flex-wrap: wrap; } + .flex-nowrap-l { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } + .flex-wrap-reverse-l { -ms-flex-wrap: wrap-reverse; flex-wrap: wrap-reverse; } + .flex-column-reverse-l { -webkit-box-orient: vertical; -webkit-box-direction: reverse; -ms-flex-direction: column-reverse; flex-direction: column-reverse; } + .flex-row-reverse-l { -webkit-box-orient: horizontal; -webkit-box-direction: reverse; -ms-flex-direction: row-reverse; flex-direction: row-reverse; } + + .items-start-l { -webkit-box-align: start; -ms-flex-align: start; align-items: flex-start; } + .items-end-l { -webkit-box-align: end; -ms-flex-align: end; align-items: flex-end; } + .items-center-l { -webkit-box-align: center; -ms-flex-align: center; align-items: center; } + .items-baseline-l { -webkit-box-align: baseline; -ms-flex-align: baseline; align-items: baseline; } + .items-stretch-l { -webkit-box-align: stretch; -ms-flex-align: stretch; align-items: stretch; } + + .self-start-l { -ms-flex-item-align: start; align-self: flex-start; } + .self-end-l { -ms-flex-item-align: end; align-self: flex-end; } + .self-center-l { -ms-flex-item-align: center; -ms-grid-row-align: center; align-self: center; } + .self-baseline-l { -ms-flex-item-align: baseline; align-self: baseline; } + .self-stretch-l { -ms-flex-item-align: stretch; -ms-grid-row-align: stretch; align-self: stretch; } + + .justify-start-l { -webkit-box-pack: start; -ms-flex-pack: start; justify-content: flex-start; } + .justify-end-l { -webkit-box-pack: end; -ms-flex-pack: end; justify-content: flex-end; } + .justify-center-l { -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; } + .justify-between-l { -webkit-box-pack: justify; -ms-flex-pack: justify; justify-content: space-between; } + .justify-around-l { -ms-flex-pack: distribute; justify-content: space-around; } + + .content-start-l { -ms-flex-line-pack: start; align-content: flex-start; } + .content-end-l { -ms-flex-line-pack: end; align-content: flex-end; } + .content-center-l { -ms-flex-line-pack: center; align-content: center; } + .content-between-l { -ms-flex-line-pack: justify; align-content: space-between; } + .content-around-l { -ms-flex-line-pack: distribute; align-content: space-around; } + .content-stretch-l { -ms-flex-line-pack: stretch; align-content: stretch; } + + .order-0-l { -webkit-box-ordinal-group: 1; -ms-flex-order: 0; order: 0; } + .order-1-l { -webkit-box-ordinal-group: 2; -ms-flex-order: 1; order: 1; } + .order-2-l { -webkit-box-ordinal-group: 3; -ms-flex-order: 2; order: 2; } + .order-3-l { -webkit-box-ordinal-group: 4; -ms-flex-order: 3; order: 3; } + .order-4-l { -webkit-box-ordinal-group: 5; -ms-flex-order: 4; order: 4; } + .order-5-l { -webkit-box-ordinal-group: 6; -ms-flex-order: 5; order: 5; } + .order-6-l { -webkit-box-ordinal-group: 7; -ms-flex-order: 6; order: 6; } + .order-7-l { -webkit-box-ordinal-group: 8; -ms-flex-order: 7; order: 7; } + .order-8-l { -webkit-box-ordinal-group: 9; -ms-flex-order: 8; order: 8; } + .order-last-l { -webkit-box-ordinal-group: 100000; -ms-flex-order: 99999; order: 99999; } + + .flex-grow-0-l { -webkit-box-flex: 0; -ms-flex-positive: 0; flex-grow: 0; } + .flex-grow-1-l { -webkit-box-flex: 1; -ms-flex-positive: 1; flex-grow: 1; } + + .flex-shrink-0-l { -ms-flex-negative: 0; flex-shrink: 0; } + .flex-shrink-1-l { -ms-flex-negative: 1; flex-shrink: 1; } +} + +/* + + FLOATS + http://tachyons.io/docs/layout/floats/ + + 1. Floated elements are automatically rendered as block level elements. + Setting floats to display inline will fix the double margin bug in + ie6. You know... just in case. + + 2. Don't forget to clearfix your floats with .cf + + Base: + f = float + + Modifiers: + l = left + r = right + n = none + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.fl { float: left; _display: inline; } + +.fr { float: right; _display: inline; } + +.fn { float: none; } + +@media screen and (min-width: 30em) { + .fl-ns { float: left; _display: inline; } + .fr-ns { float: right; _display: inline; } + .fn-ns { float: none; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .fl-m { float: left; _display: inline; } + .fr-m { float: right; _display: inline; } + .fn-m { float: none; } +} + +@media screen and (min-width: 60em) { + .fl-l { float: left; _display: inline; } + .fr-l { float: right; _display: inline; } + .fn-l { float: none; } +} + +/* + + FONT FAMILY GROUPS + Docs: http://tachyons.io/docs/typography/font-family/ + +*/ + +.sans-serif { + font-family: -apple-system, BlinkMacSystemFont, + 'avenir next', avenir, + 'helvetica neue', helvetica, + ubuntu, + roboto, noto, + 'segoe ui', arial, + sans-serif; +} + +.serif { + font-family: georgia, + times, + serif; +} + +.system-sans-serif { + font-family: sans-serif; +} + +.system-serif { + font-family: serif; +} + +/* Monospaced Typefaces (for code) */ + +/* From http://cssfontstack.com */ + +code, .code { + font-family: Consolas, + monaco, + monospace; +} + +.courier { + font-family: 'Courier Next', + courier, + monospace; +} + +/* Sans-Serif Typefaces */ + +.helvetica { + font-family: 'helvetica neue', helvetica, + sans-serif; +} + +.avenir { + font-family: 'avenir next', avenir, + sans-serif; +} + +/* Serif Typefaces */ + +.athelas { + font-family: athelas, + georgia, + serif; +} + +.georgia { + font-family: georgia, + serif; +} + +.times { + font-family: times, + serif; +} + +.bodoni { + font-family: "Bodoni MT", + serif; +} + +.calisto { + font-family: "Calisto MT", + serif; +} + +.garamond { + font-family: garamond, + serif; +} + +.baskerville { + font-family: baskerville, + serif; +} + +/* + + FONT STYLE + Docs: http://tachyons.io/docs/typography/font-style/ + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.i { font-style: italic; } + +.fs-normal { font-style: normal; } + +@media screen and (min-width: 30em) { + .i-ns { font-style: italic; } + .fs-normal-ns { font-style: normal; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .i-m { font-style: italic; } + .fs-normal-m { font-style: normal; } +} + +@media screen and (min-width: 60em) { + .i-l { font-style: italic; } + .fs-normal-l { font-style: normal; } +} + +/* + + FONT WEIGHT + Docs: http://tachyons.io/docs/typography/font-weight/ + + Base + fw = font-weight + + Modifiers: + 1 = literal value 100 + 2 = literal value 200 + 3 = literal value 300 + 4 = literal value 400 + 5 = literal value 500 + 6 = literal value 600 + 7 = literal value 700 + 8 = literal value 800 + 9 = literal value 900 + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.normal { font-weight: normal; } + +.b { font-weight: bold; } + +.fw1 { font-weight: 100; } + +.fw2 { font-weight: 200; } + +.fw3 { font-weight: 300; } + +.fw4 { font-weight: 400; } + +.fw5 { font-weight: 500; } + +.fw6 { font-weight: 600; } + +.fw7 { font-weight: 700; } + +.fw8 { font-weight: 800; } + +.fw9 { font-weight: 900; } + +@media screen and (min-width: 30em) { + .normal-ns { font-weight: normal; } + .b-ns { font-weight: bold; } + .fw1-ns { font-weight: 100; } + .fw2-ns { font-weight: 200; } + .fw3-ns { font-weight: 300; } + .fw4-ns { font-weight: 400; } + .fw5-ns { font-weight: 500; } + .fw6-ns { font-weight: 600; } + .fw7-ns { font-weight: 700; } + .fw8-ns { font-weight: 800; } + .fw9-ns { font-weight: 900; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .normal-m { font-weight: normal; } + .b-m { font-weight: bold; } + .fw1-m { font-weight: 100; } + .fw2-m { font-weight: 200; } + .fw3-m { font-weight: 300; } + .fw4-m { font-weight: 400; } + .fw5-m { font-weight: 500; } + .fw6-m { font-weight: 600; } + .fw7-m { font-weight: 700; } + .fw8-m { font-weight: 800; } + .fw9-m { font-weight: 900; } +} + +@media screen and (min-width: 60em) { + .normal-l { font-weight: normal; } + .b-l { font-weight: bold; } + .fw1-l { font-weight: 100; } + .fw2-l { font-weight: 200; } + .fw3-l { font-weight: 300; } + .fw4-l { font-weight: 400; } + .fw5-l { font-weight: 500; } + .fw6-l { font-weight: 600; } + .fw7-l { font-weight: 700; } + .fw8-l { font-weight: 800; } + .fw9-l { font-weight: 900; } +} + +/* + + FORMS + +*/ + +.input-reset { + -webkit-appearance: none; + -moz-appearance: none; +} + +.button-reset::-moz-focus-inner, +.input-reset::-moz-focus-inner { + border: 0; + padding: 0; +} + +/* + + HEIGHTS + Docs: http://tachyons.io/docs/layout/heights/ + + Base: + h = height + min-h = min-height + min-vh = min-height vertical screen height + vh = vertical screen height + + Modifiers + 1 = 1st step in height scale + 2 = 2nd step in height scale + 3 = 3rd step in height scale + 4 = 4th step in height scale + 5 = 5th step in height scale + + -25 = literal value 25% + -50 = literal value 50% + -75 = literal value 75% + -100 = literal value 100% + + -auto = string value of auto + -inherit = string value of inherit + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +/* Height Scale */ + +.h1 { height: 1rem; } + +.h2 { height: 2rem; } + +.h3 { height: 4rem; } + +.h4 { height: 8rem; } + +.h5 { height: 16rem; } + +/* Height Percentages - Based off of height of parent */ + +.h-25 { height: 25%; } + +.h-50 { height: 50%; } + +.h-75 { height: 75%; } + +.h-100 { height: 100%; } + +.min-h-100 { min-height: 100%; } + +/* Screen Height Percentage */ + +.vh-25 { height: 25vh; } + +.vh-50 { height: 50vh; } + +.vh-75 { height: 75vh; } + +.vh-100 { height: 100vh; } + +.min-vh-100 { min-height: 100vh; } + +/* String Properties */ + +.h-auto { height: auto; } + +.h-inherit { height: inherit; } + +@media screen and (min-width: 30em) { + .h1-ns { height: 1rem; } + .h2-ns { height: 2rem; } + .h3-ns { height: 4rem; } + .h4-ns { height: 8rem; } + .h5-ns { height: 16rem; } + .h-25-ns { height: 25%; } + .h-50-ns { height: 50%; } + .h-75-ns { height: 75%; } + .h-100-ns { height: 100%; } + .min-h-100-ns { min-height: 100%; } + .vh-25-ns { height: 25vh; } + .vh-50-ns { height: 50vh; } + .vh-75-ns { height: 75vh; } + .vh-100-ns { height: 100vh; } + .min-vh-100-ns { min-height: 100vh; } + .h-auto-ns { height: auto; } + .h-inherit-ns { height: inherit; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .h1-m { height: 1rem; } + .h2-m { height: 2rem; } + .h3-m { height: 4rem; } + .h4-m { height: 8rem; } + .h5-m { height: 16rem; } + .h-25-m { height: 25%; } + .h-50-m { height: 50%; } + .h-75-m { height: 75%; } + .h-100-m { height: 100%; } + .min-h-100-m { min-height: 100%; } + .vh-25-m { height: 25vh; } + .vh-50-m { height: 50vh; } + .vh-75-m { height: 75vh; } + .vh-100-m { height: 100vh; } + .min-vh-100-m { min-height: 100vh; } + .h-auto-m { height: auto; } + .h-inherit-m { height: inherit; } +} + +@media screen and (min-width: 60em) { + .h1-l { height: 1rem; } + .h2-l { height: 2rem; } + .h3-l { height: 4rem; } + .h4-l { height: 8rem; } + .h5-l { height: 16rem; } + .h-25-l { height: 25%; } + .h-50-l { height: 50%; } + .h-75-l { height: 75%; } + .h-100-l { height: 100%; } + .min-h-100-l { min-height: 100%; } + .vh-25-l { height: 25vh; } + .vh-50-l { height: 50vh; } + .vh-75-l { height: 75vh; } + .vh-100-l { height: 100vh; } + .min-vh-100-l { min-height: 100vh; } + .h-auto-l { height: auto; } + .h-inherit-l { height: inherit; } +} + +/* + + LETTER SPACING + Docs: http://tachyons.io/docs/typography/tracking/ + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.tracked { letter-spacing: .1em; } + +.tracked-tight { letter-spacing: -.05em; } + +.tracked-mega { letter-spacing: .25em; } + +@media screen and (min-width: 30em) { + .tracked-ns { letter-spacing: .1em; } + .tracked-tight-ns { letter-spacing: -.05em; } + .tracked-mega-ns { letter-spacing: .25em; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .tracked-m { letter-spacing: .1em; } + .tracked-tight-m { letter-spacing: -.05em; } + .tracked-mega-m { letter-spacing: .25em; } +} + +@media screen and (min-width: 60em) { + .tracked-l { letter-spacing: .1em; } + .tracked-tight-l { letter-spacing: -.05em; } + .tracked-mega-l { letter-spacing: .25em; } +} + +/* + + LINE HEIGHT / LEADING + Docs: http://tachyons.io/docs/typography/line-height + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.lh-solid { line-height: 1; } + +.lh-title { line-height: 1.25; } + +.lh-copy { line-height: 1.5; } + +@media screen and (min-width: 30em) { + .lh-solid-ns { line-height: 1; } + .lh-title-ns { line-height: 1.25; } + .lh-copy-ns { line-height: 1.5; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .lh-solid-m { line-height: 1; } + .lh-title-m { line-height: 1.25; } + .lh-copy-m { line-height: 1.5; } +} + +@media screen and (min-width: 60em) { + .lh-solid-l { line-height: 1; } + .lh-title-l { line-height: 1.25; } + .lh-copy-l { line-height: 1.5; } +} + +/* + + LINKS + Docs: http://tachyons.io/docs/elements/links/ + +*/ + +.link { + text-decoration: none; + transition: color .15s ease-in; +} + +.link:link, +.link:visited { + transition: color .15s ease-in; +} + +.link:hover { + transition: color .15s ease-in; +} + +.link:active { + transition: color .15s ease-in; +} + +.link:focus { + transition: color .15s ease-in; + outline: 1px dotted currentColor; +} + +/* + + LISTS + http://tachyons.io/docs/elements/lists/ + +*/ + +.list { list-style-type: none; } + +/* + + MAX WIDTHS + Docs: http://tachyons.io/docs/layout/max-widths/ + + Base: + mw = max-width + + Modifiers + 1 = 1st step in width scale + 2 = 2nd step in width scale + 3 = 3rd step in width scale + 4 = 4th step in width scale + 5 = 5th step in width scale + 6 = 6st step in width scale + 7 = 7nd step in width scale + 8 = 8rd step in width scale + 9 = 9th step in width scale + + -100 = literal value 100% + + -none = string value none + + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +/* Max Width Percentages */ + +.mw-100 { max-width: 100%; } + +/* Max Width Scale */ + +.mw1 { max-width: 1rem; } + +.mw2 { max-width: 2rem; } + +.mw3 { max-width: 4rem; } + +.mw4 { max-width: 8rem; } + +.mw5 { max-width: 16rem; } + +.mw6 { max-width: 32rem; } + +.mw7 { max-width: 48rem; } + +.mw8 { max-width: 64rem; } + +.mw9 { max-width: 96rem; } + +/* Max Width String Properties */ + +.mw-none { max-width: none; } + +@media screen and (min-width: 30em) { + .mw-100-ns { max-width: 100%; } + + .mw1-ns { max-width: 1rem; } + .mw2-ns { max-width: 2rem; } + .mw3-ns { max-width: 4rem; } + .mw4-ns { max-width: 8rem; } + .mw5-ns { max-width: 16rem; } + .mw6-ns { max-width: 32rem; } + .mw7-ns { max-width: 48rem; } + .mw8-ns { max-width: 64rem; } + .mw9-ns { max-width: 96rem; } + + .mw-none-ns { max-width: none; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .mw-100-m { max-width: 100%; } + + .mw1-m { max-width: 1rem; } + .mw2-m { max-width: 2rem; } + .mw3-m { max-width: 4rem; } + .mw4-m { max-width: 8rem; } + .mw5-m { max-width: 16rem; } + .mw6-m { max-width: 32rem; } + .mw7-m { max-width: 48rem; } + .mw8-m { max-width: 64rem; } + .mw9-m { max-width: 96rem; } + + .mw-none-m { max-width: none; } +} + +@media screen and (min-width: 60em) { + .mw-100-l { max-width: 100%; } + + .mw1-l { max-width: 1rem; } + .mw2-l { max-width: 2rem; } + .mw3-l { max-width: 4rem; } + .mw4-l { max-width: 8rem; } + .mw5-l { max-width: 16rem; } + .mw6-l { max-width: 32rem; } + .mw7-l { max-width: 48rem; } + .mw8-l { max-width: 64rem; } + .mw9-l { max-width: 96rem; } + + .mw-none-l { max-width: none; } +} + +/* + + WIDTHS + Docs: http://tachyons.io/docs/layout/widths/ + + Base: + w = width + + Modifiers + 1 = 1st step in width scale + 2 = 2nd step in width scale + 3 = 3rd step in width scale + 4 = 4th step in width scale + 5 = 5th step in width scale + + -10 = literal value 10% + -20 = literal value 20% + -25 = literal value 25% + -30 = literal value 30% + -33 = literal value 33% + -34 = literal value 34% + -40 = literal value 40% + -50 = literal value 50% + -60 = literal value 60% + -70 = literal value 70% + -75 = literal value 75% + -80 = literal value 80% + -90 = literal value 90% + -100 = literal value 100% + + -third = 100% / 3 (Not supported in opera mini or IE8) + -two-thirds = 100% / 1.5 (Not supported in opera mini or IE8) + -auto = string value auto + + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +/* Width Scale */ + +.w1 { width: 1rem; } + +.w2 { width: 2rem; } + +.w3 { width: 4rem; } + +.w4 { width: 8rem; } + +.w5 { width: 16rem; } + +.w-10 { width: 10%; } + +.w-20 { width: 20%; } + +.w-25 { width: 25%; } + +.w-30 { width: 30%; } + +.w-33 { width: 33%; } + +.w-34 { width: 34%; } + +.w-40 { width: 40%; } + +.w-50 { width: 50%; } + +.w-60 { width: 60%; } + +.w-70 { width: 70%; } + +.w-75 { width: 75%; } + +.w-80 { width: 80%; } + +.w-90 { width: 90%; } + +.w-100 { width: 100%; } + +.w-third { width: 33.33333%; } + +.w-two-thirds { width: 66.66667%; } + +.w-auto { width: auto; } + +@media screen and (min-width: 30em) { + .w1-ns { width: 1rem; } + .w2-ns { width: 2rem; } + .w3-ns { width: 4rem; } + .w4-ns { width: 8rem; } + .w5-ns { width: 16rem; } + .w-10-ns { width: 10%; } + .w-20-ns { width: 20%; } + .w-25-ns { width: 25%; } + .w-30-ns { width: 30%; } + .w-33-ns { width: 33%; } + .w-34-ns { width: 34%; } + .w-40-ns { width: 40%; } + .w-50-ns { width: 50%; } + .w-60-ns { width: 60%; } + .w-70-ns { width: 70%; } + .w-75-ns { width: 75%; } + .w-80-ns { width: 80%; } + .w-90-ns { width: 90%; } + .w-100-ns { width: 100%; } + .w-third-ns { width: 33.33333%; } + .w-two-thirds-ns { width: 66.66667%; } + .w-auto-ns { width: auto; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .w1-m { width: 1rem; } + .w2-m { width: 2rem; } + .w3-m { width: 4rem; } + .w4-m { width: 8rem; } + .w5-m { width: 16rem; } + .w-10-m { width: 10%; } + .w-20-m { width: 20%; } + .w-25-m { width: 25%; } + .w-30-m { width: 30%; } + .w-33-m { width: 33%; } + .w-34-m { width: 34%; } + .w-40-m { width: 40%; } + .w-50-m { width: 50%; } + .w-60-m { width: 60%; } + .w-70-m { width: 70%; } + .w-75-m { width: 75%; } + .w-80-m { width: 80%; } + .w-90-m { width: 90%; } + .w-100-m { width: 100%; } + .w-third-m { width: 33.33333%; } + .w-two-thirds-m { width: 66.66667%; } + .w-auto-m { width: auto; } +} + +@media screen and (min-width: 60em) { + .w1-l { width: 1rem; } + .w2-l { width: 2rem; } + .w3-l { width: 4rem; } + .w4-l { width: 8rem; } + .w5-l { width: 16rem; } + .w-10-l { width: 10%; } + .w-20-l { width: 20%; } + .w-25-l { width: 25%; } + .w-30-l { width: 30%; } + .w-33-l { width: 33%; } + .w-34-l { width: 34%; } + .w-40-l { width: 40%; } + .w-50-l { width: 50%; } + .w-60-l { width: 60%; } + .w-70-l { width: 70%; } + .w-75-l { width: 75%; } + .w-80-l { width: 80%; } + .w-90-l { width: 90%; } + .w-100-l { width: 100%; } + .w-third-l { width: 33.33333%; } + .w-two-thirds-l { width: 66.66667%; } + .w-auto-l { width: auto; } +} + +/* + + OVERFLOW + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + + */ + +.overflow-visible { overflow: visible; } + +.overflow-hidden { overflow: hidden; } + +.overflow-scroll { overflow: scroll; } + +.overflow-auto { overflow: auto; } + +.overflow-x-visible { overflow-x: visible; } + +.overflow-x-hidden { overflow-x: hidden; } + +.overflow-x-scroll { overflow-x: scroll; } + +.overflow-x-auto { overflow-x: auto; } + +.overflow-y-visible { overflow-y: visible; } + +.overflow-y-hidden { overflow-y: hidden; } + +.overflow-y-scroll { overflow-y: scroll; } + +.overflow-y-auto { overflow-y: auto; } + +@media screen and (min-width: 30em) { + .overflow-visible-ns { overflow: visible; } + .overflow-hidden-ns { overflow: hidden; } + .overflow-scroll-ns { overflow: scroll; } + .overflow-auto-ns { overflow: auto; } + .overflow-x-visible-ns { overflow-x: visible; } + .overflow-x-hidden-ns { overflow-x: hidden; } + .overflow-x-scroll-ns { overflow-x: scroll; } + .overflow-x-auto-ns { overflow-x: auto; } + + .overflow-y-visible-ns { overflow-y: visible; } + .overflow-y-hidden-ns { overflow-y: hidden; } + .overflow-y-scroll-ns { overflow-y: scroll; } + .overflow-y-auto-ns { overflow-y: auto; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .overflow-visible-m { overflow: visible; } + .overflow-hidden-m { overflow: hidden; } + .overflow-scroll-m { overflow: scroll; } + .overflow-auto-m { overflow: auto; } + + .overflow-x-visible-m { overflow-x: visible; } + .overflow-x-hidden-m { overflow-x: hidden; } + .overflow-x-scroll-m { overflow-x: scroll; } + .overflow-x-auto-m { overflow-x: auto; } + + .overflow-y-visible-m { overflow-y: visible; } + .overflow-y-hidden-m { overflow-y: hidden; } + .overflow-y-scroll-m { overflow-y: scroll; } + .overflow-y-auto-m { overflow-y: auto; } +} + +@media screen and (min-width: 60em) { + .overflow-visible-l { overflow: visible; } + .overflow-hidden-l { overflow: hidden; } + .overflow-scroll-l { overflow: scroll; } + .overflow-auto-l { overflow: auto; } + + .overflow-x-visible-l { overflow-x: visible; } + .overflow-x-hidden-l { overflow-x: hidden; } + .overflow-x-scroll-l { overflow-x: scroll; } + .overflow-x-auto-l { overflow-x: auto; } + + .overflow-y-visible-l { overflow-y: visible; } + .overflow-y-hidden-l { overflow-y: hidden; } + .overflow-y-scroll-l { overflow-y: scroll; } + .overflow-y-auto-l { overflow-y: auto; } +} + +/* + + POSITIONING + Docs: http://tachyons.io/docs/layout/position/ + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.static { position: static; } + +.relative { position: relative; } + +.absolute { position: absolute; } + +.fixed { position: fixed; } + +@media screen and (min-width: 30em) { + .static-ns { position: static; } + .relative-ns { position: relative; } + .absolute-ns { position: absolute; } + .fixed-ns { position: fixed; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .static-m { position: static; } + .relative-m { position: relative; } + .absolute-m { position: absolute; } + .fixed-m { position: fixed; } +} + +@media screen and (min-width: 60em) { + .static-l { position: static; } + .relative-l { position: relative; } + .absolute-l { position: absolute; } + .fixed-l { position: fixed; } +} + +/* + + OPACITY + Docs: http://tachyons.io/docs/themes/opacity/ + +*/ + +.o-100 { opacity: 1; } + +.o-90 { opacity: .9; } + +.o-80 { opacity: .8; } + +.o-70 { opacity: .7; } + +.o-60 { opacity: .6; } + +.o-50 { opacity: .5; } + +.o-40 { opacity: .4; } + +.o-30 { opacity: .3; } + +.o-20 { opacity: .2; } + +.o-10 { opacity: .1; } + +.o-05 { opacity: .05; } + +.o-025 { opacity: .025; } + +.o-0 { opacity: 0; } + +/* + + ROTATIONS + +*/ + +.rotate-45 { -webkit-transform: rotate(45deg); transform: rotate(45deg); } + +.rotate-90 { -webkit-transform: rotate(90deg); transform: rotate(90deg); } + +.rotate-135 { -webkit-transform: rotate(135deg); transform: rotate(135deg); } + +.rotate-180 { -webkit-transform: rotate(180deg); transform: rotate(180deg); } + +.rotate-225 { -webkit-transform: rotate(225deg); transform: rotate(225deg); } + +.rotate-270 { -webkit-transform: rotate(270deg); transform: rotate(270deg); } + +.rotate-315 { -webkit-transform: rotate(315deg); transform: rotate(315deg); } + +@media screen and (min-width: 30em){ + .rotate-45-ns { -webkit-transform: rotate(45deg); transform: rotate(45deg); } + .rotate-90-ns { -webkit-transform: rotate(90deg); transform: rotate(90deg); } + .rotate-135-ns { -webkit-transform: rotate(135deg); transform: rotate(135deg); } + .rotate-180-ns { -webkit-transform: rotate(180deg); transform: rotate(180deg); } + .rotate-225-ns { -webkit-transform: rotate(225deg); transform: rotate(225deg); } + .rotate-270-ns { -webkit-transform: rotate(270deg); transform: rotate(270deg); } + .rotate-315-ns { -webkit-transform: rotate(315deg); transform: rotate(315deg); } +} + +@media screen and (min-width: 30em) and (max-width: 60em){ + .rotate-45-m { -webkit-transform: rotate(45deg); transform: rotate(45deg); } + .rotate-90-m { -webkit-transform: rotate(90deg); transform: rotate(90deg); } + .rotate-135-m { -webkit-transform: rotate(135deg); transform: rotate(135deg); } + .rotate-180-m { -webkit-transform: rotate(180deg); transform: rotate(180deg); } + .rotate-225-m { -webkit-transform: rotate(225deg); transform: rotate(225deg); } + .rotate-270-m { -webkit-transform: rotate(270deg); transform: rotate(270deg); } + .rotate-315-m { -webkit-transform: rotate(315deg); transform: rotate(315deg); } +} + +@media screen and (min-width: 60em){ + .rotate-45-l { -webkit-transform: rotate(45deg); transform: rotate(45deg); } + .rotate-90-l { -webkit-transform: rotate(90deg); transform: rotate(90deg); } + .rotate-135-l { -webkit-transform: rotate(135deg); transform: rotate(135deg); } + .rotate-180-l { -webkit-transform: rotate(180deg); transform: rotate(180deg); } + .rotate-225-l { -webkit-transform: rotate(225deg); transform: rotate(225deg); } + .rotate-270-l { -webkit-transform: rotate(270deg); transform: rotate(270deg); } + .rotate-315-l { -webkit-transform: rotate(315deg); transform: rotate(315deg); } +} + +/* + + SKINS + Docs: http://tachyons.io/docs/themes/skins/ + + Classes for setting foreground and background colors on elements. + If you haven't declared a border color, but set border on an element, it will + be set to the current text color. + +*/ + +/* Text colors */ + +.black-90 { color: rgba(0, 0, 0, .9); } + +.black-80 { color: rgba(0, 0, 0, .8); } + +.black-70 { color: rgba(0, 0, 0, .7); } + +.black-60 { color: rgba(0, 0, 0, .6); } + +.black-50 { color: rgba(0, 0, 0, .5); } + +.black-40 { color: rgba(0, 0, 0, .4); } + +.black-30 { color: rgba(0, 0, 0, .3); } + +.black-20 { color: rgba(0, 0, 0, .2); } + +.black-10 { color: rgba(0, 0, 0, .1); } + +.black-05 { color: rgba(0, 0, 0, .05); } + +.white-90 { color: rgba(255, 255, 255, .9); } + +.white-80 { color: rgba(255, 255, 255, .8); } + +.white-70 { color: rgba(255, 255, 255, .7); } + +.white-60 { color: rgba(255, 255, 255, .6); } + +.white-50 { color: rgba(255, 255, 255, .5); } + +.white-40 { color: rgba(255, 255, 255, .4); } + +.white-30 { color: rgba(255, 255, 255, .3); } + +.white-20 { color: rgba(255, 255, 255, .2); } + +.white-10 { color: rgba(255, 255, 255, .1); } + +.black { color: #000; } + +.near-black { color: #111; } + +.dark-gray { color: #333; } + +.mid-gray { color: #555; } + +.gray { color: #777; } + +.silver { color: #999; } + +.light-silver { color: #aaa; } + +.moon-gray { color: #ccc; } + +.light-gray { color: #eee; } + +.near-white { color: #f4f4f4; } + +.white { color: #fff; } + +.dark-red { color: #e7040f; } + +.red { color: #ff4136; } + +.light-red { color: #ff725c; } + +.orange { color: #ff6300; } + +.gold { color: #ffb700; } + +.yellow { color: #ffd700; } + +.light-yellow { color: #fbf1a9; } + +.purple { color: #5e2ca5; } + +.light-purple { color: #a463f2; } + +.dark-pink { color: #d5008f; } + +.hot-pink { color: #ff41b4; } + +.pink { color: #ff80cc; } + +.light-pink { color: #ffa3d7; } + +.dark-green { color: #137752; } + +.green { color: #19a974; } + +.light-green { color: #9eebcf; } + +.navy { color: #001b44; } + +.dark-blue { color: #00449e; } + +.blue { color: #357edd; } + +.light-blue { color: #96ccff; } + +.lightest-blue { color: #cdecff; } + +.washed-blue { color: #f6fffe; } + +.washed-green { color: #e8fdf5; } + +.washed-yellow { color: #fffceb; } + +.washed-red { color: #ffdfdf; } + +.color-inherit { color: inherit; } + +.bg-black-90 { background-color: rgba(0, 0, 0, .9); } + +.bg-black-80 { background-color: rgba(0, 0, 0, .8); } + +.bg-black-70 { background-color: rgba(0, 0, 0, .7); } + +.bg-black-60 { background-color: rgba(0, 0, 0, .6); } + +.bg-black-50 { background-color: rgba(0, 0, 0, .5); } + +.bg-black-40 { background-color: rgba(0, 0, 0, .4); } + +.bg-black-30 { background-color: rgba(0, 0, 0, .3); } + +.bg-black-20 { background-color: rgba(0, 0, 0, .2); } + +.bg-black-10 { background-color: rgba(0, 0, 0, .1); } + +.bg-black-05 { background-color: rgba(0, 0, 0, .05); } + +.bg-white-90 { background-color: rgba(255, 255, 255, .9); } + +.bg-white-80 { background-color: rgba(255, 255, 255, .8); } + +.bg-white-70 { background-color: rgba(255, 255, 255, .7); } + +.bg-white-60 { background-color: rgba(255, 255, 255, .6); } + +.bg-white-50 { background-color: rgba(255, 255, 255, .5); } + +.bg-white-40 { background-color: rgba(255, 255, 255, .4); } + +.bg-white-30 { background-color: rgba(255, 255, 255, .3); } + +.bg-white-20 { background-color: rgba(255, 255, 255, .2); } + +.bg-white-10 { background-color: rgba(255, 255, 255, .1); } + +/* Background colors */ + +.bg-black { background-color: #000; } + +.bg-near-black { background-color: #111; } + +.bg-dark-gray { background-color: #333; } + +.bg-mid-gray { background-color: #555; } + +.bg-gray { background-color: #777; } + +.bg-silver { background-color: #999; } + +.bg-light-silver { background-color: #aaa; } + +.bg-moon-gray { background-color: #ccc; } + +.bg-light-gray { background-color: #eee; } + +.bg-near-white { background-color: #f4f4f4; } + +.bg-white { background-color: #fff; } + +.bg-transparent { background-color: transparent; } + +.bg-dark-red { background-color: #e7040f; } + +.bg-red { background-color: #ff4136; } + +.bg-light-red { background-color: #ff725c; } + +.bg-orange { background-color: #ff6300; } + +.bg-gold { background-color: #ffb700; } + +.bg-yellow { background-color: #ffd700; } + +.bg-light-yellow { background-color: #fbf1a9; } + +.bg-purple { background-color: #5e2ca5; } + +.bg-light-purple { background-color: #a463f2; } + +.bg-dark-pink { background-color: #d5008f; } + +.bg-hot-pink { background-color: #ff41b4; } + +.bg-pink { background-color: #ff80cc; } + +.bg-light-pink { background-color: #ffa3d7; } + +.bg-dark-green { background-color: #137752; } + +.bg-green { background-color: #19a974; } + +.bg-light-green { background-color: #9eebcf; } + +.bg-navy { background-color: #001b44; } + +.bg-dark-blue { background-color: #00449e; } + +.bg-blue { background-color: #357edd; } + +.bg-light-blue { background-color: #96ccff; } + +.bg-lightest-blue { background-color: #cdecff; } + +.bg-washed-blue { background-color: #f6fffe; } + +.bg-washed-green { background-color: #e8fdf5; } + +.bg-washed-yellow { background-color: #fffceb; } + +.bg-washed-red { background-color: #ffdfdf; } + +.bg-inherit { background-color: inherit; } + +/* + + SKINS:PSEUDO + + Customize the color of an element when + it is focused or hovered over. + + */ + +.hover-black:hover, +.hover-black:focus { color: #000; } + +.hover-near-black:hover, +.hover-near-black:focus { color: #111; } + +.hover-dark-gray:hover, +.hover-dark-gray:focus { color: #333; } + +.hover-mid-gray:hover, +.hover-mid-gray:focus { color: #555; } + +.hover-gray:hover, +.hover-gray:focus { color: #777; } + +.hover-silver:hover, +.hover-silver:focus { color: #999; } + +.hover-light-silver:hover, +.hover-light-silver:focus { color: #aaa; } + +.hover-moon-gray:hover, +.hover-moon-gray:focus { color: #ccc; } + +.hover-light-gray:hover, +.hover-light-gray:focus { color: #eee; } + +.hover-near-white:hover, +.hover-near-white:focus { color: #f4f4f4; } + +.hover-white:hover, +.hover-white:focus { color: #fff; } + +.hover-black-90:hover, +.hover-black-90:focus { color: rgba(0, 0, 0, .9); } + +.hover-black-80:hover, +.hover-black-80:focus { color: rgba(0, 0, 0, .8); } + +.hover-black-70:hover, +.hover-black-70:focus { color: rgba(0, 0, 0, .7); } + +.hover-black-60:hover, +.hover-black-60:focus { color: rgba(0, 0, 0, .6); } + +.hover-black-50:hover, +.hover-black-50:focus { color: rgba(0, 0, 0, .5); } + +.hover-black-40:hover, +.hover-black-40:focus { color: rgba(0, 0, 0, .4); } + +.hover-black-30:hover, +.hover-black-30:focus { color: rgba(0, 0, 0, .3); } + +.hover-black-20:hover, +.hover-black-20:focus { color: rgba(0, 0, 0, .2); } + +.hover-black-10:hover, +.hover-black-10:focus { color: rgba(0, 0, 0, .1); } + +.hover-white-90:hover, +.hover-white-90:focus { color: rgba(255, 255, 255, .9); } + +.hover-white-80:hover, +.hover-white-80:focus { color: rgba(255, 255, 255, .8); } + +.hover-white-70:hover, +.hover-white-70:focus { color: rgba(255, 255, 255, .7); } + +.hover-white-60:hover, +.hover-white-60:focus { color: rgba(255, 255, 255, .6); } + +.hover-white-50:hover, +.hover-white-50:focus { color: rgba(255, 255, 255, .5); } + +.hover-white-40:hover, +.hover-white-40:focus { color: rgba(255, 255, 255, .4); } + +.hover-white-30:hover, +.hover-white-30:focus { color: rgba(255, 255, 255, .3); } + +.hover-white-20:hover, +.hover-white-20:focus { color: rgba(255, 255, 255, .2); } + +.hover-white-10:hover, +.hover-white-10:focus { color: rgba(255, 255, 255, .1); } + +.hover-inherit:hover, +.hover-inherit:focus { color: inherit; } + +.hover-bg-black:hover, +.hover-bg-black:focus { background-color: #000; } + +.hover-bg-near-black:hover, +.hover-bg-near-black:focus { background-color: #111; } + +.hover-bg-dark-gray:hover, +.hover-bg-dark-gray:focus { background-color: #333; } + +.hover-bg-mid-gray:hover, +.hover-bg-mid-gray:focus { background-color: #555; } + +.hover-bg-gray:hover, +.hover-bg-gray:focus { background-color: #777; } + +.hover-bg-silver:hover, +.hover-bg-silver:focus { background-color: #999; } + +.hover-bg-light-silver:hover, +.hover-bg-light-silver:focus { background-color: #aaa; } + +.hover-bg-moon-gray:hover, +.hover-bg-moon-gray:focus { background-color: #ccc; } + +.hover-bg-light-gray:hover, +.hover-bg-light-gray:focus { background-color: #eee; } + +.hover-bg-near-white:hover, +.hover-bg-near-white:focus { background-color: #f4f4f4; } + +.hover-bg-white:hover, +.hover-bg-white:focus { background-color: #fff; } + +.hover-bg-transparent:hover, +.hover-bg-transparent:focus { background-color: transparent; } + +.hover-bg-black-90:hover, +.hover-bg-black-90:focus { background-color: rgba(0, 0, 0, .9); } + +.hover-bg-black-80:hover, +.hover-bg-black-80:focus { background-color: rgba(0, 0, 0, .8); } + +.hover-bg-black-70:hover, +.hover-bg-black-70:focus { background-color: rgba(0, 0, 0, .7); } + +.hover-bg-black-60:hover, +.hover-bg-black-60:focus { background-color: rgba(0, 0, 0, .6); } + +.hover-bg-black-50:hover, +.hover-bg-black-50:focus { background-color: rgba(0, 0, 0, .5); } + +.hover-bg-black-40:hover, +.hover-bg-black-40:focus { background-color: rgba(0, 0, 0, .4); } + +.hover-bg-black-30:hover, +.hover-bg-black-30:focus { background-color: rgba(0, 0, 0, .3); } + +.hover-bg-black-20:hover, +.hover-bg-black-20:focus { background-color: rgba(0, 0, 0, .2); } + +.hover-bg-black-10:hover, +.hover-bg-black-10:focus { background-color: rgba(0, 0, 0, .1); } + +.hover-bg-white-90:hover, +.hover-bg-white-90:focus { background-color: rgba(255, 255, 255, .9); } + +.hover-bg-white-80:hover, +.hover-bg-white-80:focus { background-color: rgba(255, 255, 255, .8); } + +.hover-bg-white-70:hover, +.hover-bg-white-70:focus { background-color: rgba(255, 255, 255, .7); } + +.hover-bg-white-60:hover, +.hover-bg-white-60:focus { background-color: rgba(255, 255, 255, .6); } + +.hover-bg-white-50:hover, +.hover-bg-white-50:focus { background-color: rgba(255, 255, 255, .5); } + +.hover-bg-white-40:hover, +.hover-bg-white-40:focus { background-color: rgba(255, 255, 255, .4); } + +.hover-bg-white-30:hover, +.hover-bg-white-30:focus { background-color: rgba(255, 255, 255, .3); } + +.hover-bg-white-20:hover, +.hover-bg-white-20:focus { background-color: rgba(255, 255, 255, .2); } + +.hover-bg-white-10:hover, +.hover-bg-white-10:focus { background-color: rgba(255, 255, 255, .1); } + +.hover-dark-red:hover, +.hover-dark-red:focus { color: #e7040f; } + +.hover-red:hover, +.hover-red:focus { color: #ff4136; } + +.hover-light-red:hover, +.hover-light-red:focus { color: #ff725c; } + +.hover-orange:hover, +.hover-orange:focus { color: #ff6300; } + +.hover-gold:hover, +.hover-gold:focus { color: #ffb700; } + +.hover-yellow:hover, +.hover-yellow:focus { color: #ffd700; } + +.hover-light-yellow:hover, +.hover-light-yellow:focus { color: #fbf1a9; } + +.hover-purple:hover, +.hover-purple:focus { color: #5e2ca5; } + +.hover-light-purple:hover, +.hover-light-purple:focus { color: #a463f2; } + +.hover-dark-pink:hover, +.hover-dark-pink:focus { color: #d5008f; } + +.hover-hot-pink:hover, +.hover-hot-pink:focus { color: #ff41b4; } + +.hover-pink:hover, +.hover-pink:focus { color: #ff80cc; } + +.hover-light-pink:hover, +.hover-light-pink:focus { color: #ffa3d7; } + +.hover-dark-green:hover, +.hover-dark-green:focus { color: #137752; } + +.hover-green:hover, +.hover-green:focus { color: #19a974; } + +.hover-light-green:hover, +.hover-light-green:focus { color: #9eebcf; } + +.hover-navy:hover, +.hover-navy:focus { color: #001b44; } + +.hover-dark-blue:hover, +.hover-dark-blue:focus { color: #00449e; } + +.hover-blue:hover, +.hover-blue:focus { color: #357edd; } + +.hover-light-blue:hover, +.hover-light-blue:focus { color: #96ccff; } + +.hover-lightest-blue:hover, +.hover-lightest-blue:focus { color: #cdecff; } + +.hover-washed-blue:hover, +.hover-washed-blue:focus { color: #f6fffe; } + +.hover-washed-green:hover, +.hover-washed-green:focus { color: #e8fdf5; } + +.hover-washed-yellow:hover, +.hover-washed-yellow:focus { color: #fffceb; } + +.hover-washed-red:hover, +.hover-washed-red:focus { color: #ffdfdf; } + +.hover-bg-dark-red:hover, +.hover-bg-dark-red:focus { background-color: #e7040f; } + +.hover-bg-red:hover, +.hover-bg-red:focus { background-color: #ff4136; } + +.hover-bg-light-red:hover, +.hover-bg-light-red:focus { background-color: #ff725c; } + +.hover-bg-orange:hover, +.hover-bg-orange:focus { background-color: #ff6300; } + +.hover-bg-gold:hover, +.hover-bg-gold:focus { background-color: #ffb700; } + +.hover-bg-yellow:hover, +.hover-bg-yellow:focus { background-color: #ffd700; } + +.hover-bg-light-yellow:hover, +.hover-bg-light-yellow:focus { background-color: #fbf1a9; } + +.hover-bg-purple:hover, +.hover-bg-purple:focus { background-color: #5e2ca5; } + +.hover-bg-light-purple:hover, +.hover-bg-light-purple:focus { background-color: #a463f2; } + +.hover-bg-dark-pink:hover, +.hover-bg-dark-pink:focus { background-color: #d5008f; } + +.hover-bg-hot-pink:hover, +.hover-bg-hot-pink:focus { background-color: #ff41b4; } + +.hover-bg-pink:hover, +.hover-bg-pink:focus { background-color: #ff80cc; } + +.hover-bg-light-pink:hover, +.hover-bg-light-pink:focus { background-color: #ffa3d7; } + +.hover-bg-dark-green:hover, +.hover-bg-dark-green:focus { background-color: #137752; } + +.hover-bg-green:hover, +.hover-bg-green:focus { background-color: #19a974; } + +.hover-bg-light-green:hover, +.hover-bg-light-green:focus { background-color: #9eebcf; } + +.hover-bg-navy:hover, +.hover-bg-navy:focus { background-color: #001b44; } + +.hover-bg-dark-blue:hover, +.hover-bg-dark-blue:focus { background-color: #00449e; } + +.hover-bg-blue:hover, +.hover-bg-blue:focus { background-color: #357edd; } + +.hover-bg-light-blue:hover, +.hover-bg-light-blue:focus { background-color: #96ccff; } + +.hover-bg-lightest-blue:hover, +.hover-bg-lightest-blue:focus { background-color: #cdecff; } + +.hover-bg-washed-blue:hover, +.hover-bg-washed-blue:focus { background-color: #f6fffe; } + +.hover-bg-washed-green:hover, +.hover-bg-washed-green:focus { background-color: #e8fdf5; } + +.hover-bg-washed-yellow:hover, +.hover-bg-washed-yellow:focus { background-color: #fffceb; } + +.hover-bg-washed-red:hover, +.hover-bg-washed-red:focus { background-color: #ffdfdf; } + +.hover-bg-inherit:hover, +.hover-bg-inherit:focus { background-color: inherit; } + +/* Variables */ + +/* + SPACING + Docs: http://tachyons.io/docs/layout/spacing/ + + An eight step powers of two scale ranging from 0 to 16rem. + + Base: + p = padding + m = margin + + Modifiers: + a = all + h = horizontal + v = vertical + t = top + r = right + b = bottom + l = left + + 0 = none + 1 = 1st step in spacing scale + 2 = 2nd step in spacing scale + 3 = 3rd step in spacing scale + 4 = 4th step in spacing scale + 5 = 5th step in spacing scale + 6 = 6th step in spacing scale + 7 = 7th step in spacing scale + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.pa0 { padding: 0; } + +.pa1 { padding: .25rem; } + +.pa2 { padding: .5rem; } + +.pa3 { padding: 1rem; } + +.pa4 { padding: 2rem; } + +.pa5 { padding: 4rem; } + +.pa6 { padding: 8rem; } + +.pa7 { padding: 16rem; } + +.pl0 { padding-left: 0; } + +.pl1 { padding-left: .25rem; } + +.pl2 { padding-left: .5rem; } + +.pl3 { padding-left: 1rem; } + +.pl4 { padding-left: 2rem; } + +.pl5 { padding-left: 4rem; } + +.pl6 { padding-left: 8rem; } + +.pl7 { padding-left: 16rem; } + +.pr0 { padding-right: 0; } + +.pr1 { padding-right: .25rem; } + +.pr2 { padding-right: .5rem; } + +.pr3 { padding-right: 1rem; } + +.pr4 { padding-right: 2rem; } + +.pr5 { padding-right: 4rem; } + +.pr6 { padding-right: 8rem; } + +.pr7 { padding-right: 16rem; } + +.pb0 { padding-bottom: 0; } + +.pb1 { padding-bottom: .25rem; } + +.pb2 { padding-bottom: .5rem; } + +.pb3 { padding-bottom: 1rem; } + +.pb4 { padding-bottom: 2rem; } + +.pb5 { padding-bottom: 4rem; } + +.pb6 { padding-bottom: 8rem; } + +.pb7 { padding-bottom: 16rem; } + +.pt0 { padding-top: 0; } + +.pt1 { padding-top: .25rem; } + +.pt2 { padding-top: .5rem; } + +.pt3 { padding-top: 1rem; } + +.pt4 { padding-top: 2rem; } + +.pt5 { padding-top: 4rem; } + +.pt6 { padding-top: 8rem; } + +.pt7 { padding-top: 16rem; } + +.pv0 { + padding-top: 0; + padding-bottom: 0; +} + +.pv1 { + padding-top: .25rem; + padding-bottom: .25rem; +} + +.pv2 { + padding-top: .5rem; + padding-bottom: .5rem; +} + +.pv3 { + padding-top: 1rem; + padding-bottom: 1rem; +} + +.pv4 { + padding-top: 2rem; + padding-bottom: 2rem; +} + +.pv5 { + padding-top: 4rem; + padding-bottom: 4rem; +} + +.pv6 { + padding-top: 8rem; + padding-bottom: 8rem; +} + +.pv7 { + padding-top: 16rem; + padding-bottom: 16rem; +} + +.ph0 { + padding-left: 0; + padding-right: 0; +} + +.ph1 { + padding-left: .25rem; + padding-right: .25rem; +} + +.ph2 { + padding-left: .5rem; + padding-right: .5rem; +} + +.ph3 { + padding-left: 1rem; + padding-right: 1rem; +} + +.ph4 { + padding-left: 2rem; + padding-right: 2rem; +} + +.ph5 { + padding-left: 4rem; + padding-right: 4rem; +} + +.ph6 { + padding-left: 8rem; + padding-right: 8rem; +} + +.ph7 { + padding-left: 16rem; + padding-right: 16rem; +} + +.ma0 { margin: 0; } + +.ma1 { margin: .25rem; } + +.ma2 { margin: .5rem; } + +.ma3 { margin: 1rem; } + +.ma4 { margin: 2rem; } + +.ma5 { margin: 4rem; } + +.ma6 { margin: 8rem; } + +.ma7 { margin: 16rem; } + +.ml0 { margin-left: 0; } + +.ml1 { margin-left: .25rem; } + +.ml2 { margin-left: .5rem; } + +.ml3 { margin-left: 1rem; } + +.ml4 { margin-left: 2rem; } + +.ml5 { margin-left: 4rem; } + +.ml6 { margin-left: 8rem; } + +.ml7 { margin-left: 16rem; } + +.mr0 { margin-right: 0; } + +.mr1 { margin-right: .25rem; } + +.mr2 { margin-right: .5rem; } + +.mr3 { margin-right: 1rem; } + +.mr4 { margin-right: 2rem; } + +.mr5 { margin-right: 4rem; } + +.mr6 { margin-right: 8rem; } + +.mr7 { margin-right: 16rem; } + +.mb0 { margin-bottom: 0; } + +.mb1 { margin-bottom: .25rem; } + +.mb2 { margin-bottom: .5rem; } + +.mb3 { margin-bottom: 1rem; } + +.mb4 { margin-bottom: 2rem; } + +.mb5 { margin-bottom: 4rem; } + +.mb6 { margin-bottom: 8rem; } + +.mb7 { margin-bottom: 16rem; } + +.mt0 { margin-top: 0; } + +.mt1 { margin-top: .25rem; } + +.mt2 { margin-top: .5rem; } + +.mt3 { margin-top: 1rem; } + +.mt4 { margin-top: 2rem; } + +.mt5 { margin-top: 4rem; } + +.mt6 { margin-top: 8rem; } + +.mt7 { margin-top: 16rem; } + +.mv0 { + margin-top: 0; + margin-bottom: 0; +} + +.mv1 { + margin-top: .25rem; + margin-bottom: .25rem; +} + +.mv2 { + margin-top: .5rem; + margin-bottom: .5rem; +} + +.mv3 { + margin-top: 1rem; + margin-bottom: 1rem; +} + +.mv4 { + margin-top: 2rem; + margin-bottom: 2rem; +} + +.mv5 { + margin-top: 4rem; + margin-bottom: 4rem; +} + +.mv6 { + margin-top: 8rem; + margin-bottom: 8rem; +} + +.mv7 { + margin-top: 16rem; + margin-bottom: 16rem; +} + +.mh0 { + margin-left: 0; + margin-right: 0; +} + +.mh1 { + margin-left: .25rem; + margin-right: .25rem; +} + +.mh2 { + margin-left: .5rem; + margin-right: .5rem; +} + +.mh3 { + margin-left: 1rem; + margin-right: 1rem; +} + +.mh4 { + margin-left: 2rem; + margin-right: 2rem; +} + +.mh5 { + margin-left: 4rem; + margin-right: 4rem; +} + +.mh6 { + margin-left: 8rem; + margin-right: 8rem; +} + +.mh7 { + margin-left: 16rem; + margin-right: 16rem; +} + +@media screen and (min-width: 30em) { + .pa0-ns { padding: 0; } + .pa1-ns { padding: .25rem; } + .pa2-ns { padding: .5rem; } + .pa3-ns { padding: 1rem; } + .pa4-ns { padding: 2rem; } + .pa5-ns { padding: 4rem; } + .pa6-ns { padding: 8rem; } + .pa7-ns { padding: 16rem; } + + .pl0-ns { padding-left: 0; } + .pl1-ns { padding-left: .25rem; } + .pl2-ns { padding-left: .5rem; } + .pl3-ns { padding-left: 1rem; } + .pl4-ns { padding-left: 2rem; } + .pl5-ns { padding-left: 4rem; } + .pl6-ns { padding-left: 8rem; } + .pl7-ns { padding-left: 16rem; } + + .pr0-ns { padding-right: 0; } + .pr1-ns { padding-right: .25rem; } + .pr2-ns { padding-right: .5rem; } + .pr3-ns { padding-right: 1rem; } + .pr4-ns { padding-right: 2rem; } + .pr5-ns { padding-right: 4rem; } + .pr6-ns { padding-right: 8rem; } + .pr7-ns { padding-right: 16rem; } + + .pb0-ns { padding-bottom: 0; } + .pb1-ns { padding-bottom: .25rem; } + .pb2-ns { padding-bottom: .5rem; } + .pb3-ns { padding-bottom: 1rem; } + .pb4-ns { padding-bottom: 2rem; } + .pb5-ns { padding-bottom: 4rem; } + .pb6-ns { padding-bottom: 8rem; } + .pb7-ns { padding-bottom: 16rem; } + + .pt0-ns { padding-top: 0; } + .pt1-ns { padding-top: .25rem; } + .pt2-ns { padding-top: .5rem; } + .pt3-ns { padding-top: 1rem; } + .pt4-ns { padding-top: 2rem; } + .pt5-ns { padding-top: 4rem; } + .pt6-ns { padding-top: 8rem; } + .pt7-ns { padding-top: 16rem; } + + .pv0-ns { + padding-top: 0; + padding-bottom: 0; + } + .pv1-ns { + padding-top: .25rem; + padding-bottom: .25rem; + } + .pv2-ns { + padding-top: .5rem; + padding-bottom: .5rem; + } + .pv3-ns { + padding-top: 1rem; + padding-bottom: 1rem; + } + .pv4-ns { + padding-top: 2rem; + padding-bottom: 2rem; + } + .pv5-ns { + padding-top: 4rem; + padding-bottom: 4rem; + } + .pv6-ns { + padding-top: 8rem; + padding-bottom: 8rem; + } + .pv7-ns { + padding-top: 16rem; + padding-bottom: 16rem; + } + .ph0-ns { + padding-left: 0; + padding-right: 0; + } + .ph1-ns { + padding-left: .25rem; + padding-right: .25rem; + } + .ph2-ns { + padding-left: .5rem; + padding-right: .5rem; + } + .ph3-ns { + padding-left: 1rem; + padding-right: 1rem; + } + .ph4-ns { + padding-left: 2rem; + padding-right: 2rem; + } + .ph5-ns { + padding-left: 4rem; + padding-right: 4rem; + } + .ph6-ns { + padding-left: 8rem; + padding-right: 8rem; + } + .ph7-ns { + padding-left: 16rem; + padding-right: 16rem; + } + + .ma0-ns { margin: 0; } + .ma1-ns { margin: .25rem; } + .ma2-ns { margin: .5rem; } + .ma3-ns { margin: 1rem; } + .ma4-ns { margin: 2rem; } + .ma5-ns { margin: 4rem; } + .ma6-ns { margin: 8rem; } + .ma7-ns { margin: 16rem; } + + .ml0-ns { margin-left: 0; } + .ml1-ns { margin-left: .25rem; } + .ml2-ns { margin-left: .5rem; } + .ml3-ns { margin-left: 1rem; } + .ml4-ns { margin-left: 2rem; } + .ml5-ns { margin-left: 4rem; } + .ml6-ns { margin-left: 8rem; } + .ml7-ns { margin-left: 16rem; } + + .mr0-ns { margin-right: 0; } + .mr1-ns { margin-right: .25rem; } + .mr2-ns { margin-right: .5rem; } + .mr3-ns { margin-right: 1rem; } + .mr4-ns { margin-right: 2rem; } + .mr5-ns { margin-right: 4rem; } + .mr6-ns { margin-right: 8rem; } + .mr7-ns { margin-right: 16rem; } + + .mb0-ns { margin-bottom: 0; } + .mb1-ns { margin-bottom: .25rem; } + .mb2-ns { margin-bottom: .5rem; } + .mb3-ns { margin-bottom: 1rem; } + .mb4-ns { margin-bottom: 2rem; } + .mb5-ns { margin-bottom: 4rem; } + .mb6-ns { margin-bottom: 8rem; } + .mb7-ns { margin-bottom: 16rem; } + + .mt0-ns { margin-top: 0; } + .mt1-ns { margin-top: .25rem; } + .mt2-ns { margin-top: .5rem; } + .mt3-ns { margin-top: 1rem; } + .mt4-ns { margin-top: 2rem; } + .mt5-ns { margin-top: 4rem; } + .mt6-ns { margin-top: 8rem; } + .mt7-ns { margin-top: 16rem; } + + .mv0-ns { + margin-top: 0; + margin-bottom: 0; + } + .mv1-ns { + margin-top: .25rem; + margin-bottom: .25rem; + } + .mv2-ns { + margin-top: .5rem; + margin-bottom: .5rem; + } + .mv3-ns { + margin-top: 1rem; + margin-bottom: 1rem; + } + .mv4-ns { + margin-top: 2rem; + margin-bottom: 2rem; + } + .mv5-ns { + margin-top: 4rem; + margin-bottom: 4rem; + } + .mv6-ns { + margin-top: 8rem; + margin-bottom: 8rem; + } + .mv7-ns { + margin-top: 16rem; + margin-bottom: 16rem; + } + + .mh0-ns { + margin-left: 0; + margin-right: 0; + } + .mh1-ns { + margin-left: .25rem; + margin-right: .25rem; + } + .mh2-ns { + margin-left: .5rem; + margin-right: .5rem; + } + .mh3-ns { + margin-left: 1rem; + margin-right: 1rem; + } + .mh4-ns { + margin-left: 2rem; + margin-right: 2rem; + } + .mh5-ns { + margin-left: 4rem; + margin-right: 4rem; + } + .mh6-ns { + margin-left: 8rem; + margin-right: 8rem; + } + .mh7-ns { + margin-left: 16rem; + margin-right: 16rem; + } + +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .pa0-m { padding: 0; } + .pa1-m { padding: .25rem; } + .pa2-m { padding: .5rem; } + .pa3-m { padding: 1rem; } + .pa4-m { padding: 2rem; } + .pa5-m { padding: 4rem; } + .pa6-m { padding: 8rem; } + .pa7-m { padding: 16rem; } + + .pl0-m { padding-left: 0; } + .pl1-m { padding-left: .25rem; } + .pl2-m { padding-left: .5rem; } + .pl3-m { padding-left: 1rem; } + .pl4-m { padding-left: 2rem; } + .pl5-m { padding-left: 4rem; } + .pl6-m { padding-left: 8rem; } + .pl7-m { padding-left: 16rem; } + + .pr0-m { padding-right: 0; } + .pr1-m { padding-right: .25rem; } + .pr2-m { padding-right: .5rem; } + .pr3-m { padding-right: 1rem; } + .pr4-m { padding-right: 2rem; } + .pr5-m { padding-right: 4rem; } + .pr6-m { padding-right: 8rem; } + .pr7-m { padding-right: 16rem; } + + .pb0-m { padding-bottom: 0; } + .pb1-m { padding-bottom: .25rem; } + .pb2-m { padding-bottom: .5rem; } + .pb3-m { padding-bottom: 1rem; } + .pb4-m { padding-bottom: 2rem; } + .pb5-m { padding-bottom: 4rem; } + .pb6-m { padding-bottom: 8rem; } + .pb7-m { padding-bottom: 16rem; } + + .pt0-m { padding-top: 0; } + .pt1-m { padding-top: .25rem; } + .pt2-m { padding-top: .5rem; } + .pt3-m { padding-top: 1rem; } + .pt4-m { padding-top: 2rem; } + .pt5-m { padding-top: 4rem; } + .pt6-m { padding-top: 8rem; } + .pt7-m { padding-top: 16rem; } + + .pv0-m { + padding-top: 0; + padding-bottom: 0; + } + .pv1-m { + padding-top: .25rem; + padding-bottom: .25rem; + } + .pv2-m { + padding-top: .5rem; + padding-bottom: .5rem; + } + .pv3-m { + padding-top: 1rem; + padding-bottom: 1rem; + } + .pv4-m { + padding-top: 2rem; + padding-bottom: 2rem; + } + .pv5-m { + padding-top: 4rem; + padding-bottom: 4rem; + } + .pv6-m { + padding-top: 8rem; + padding-bottom: 8rem; + } + .pv7-m { + padding-top: 16rem; + padding-bottom: 16rem; + } + + .ph0-m { + padding-left: 0; + padding-right: 0; + } + .ph1-m { + padding-left: .25rem; + padding-right: .25rem; + } + .ph2-m { + padding-left: .5rem; + padding-right: .5rem; + } + .ph3-m { + padding-left: 1rem; + padding-right: 1rem; + } + .ph4-m { + padding-left: 2rem; + padding-right: 2rem; + } + .ph5-m { + padding-left: 4rem; + padding-right: 4rem; + } + .ph6-m { + padding-left: 8rem; + padding-right: 8rem; + } + .ph7-m { + padding-left: 16rem; + padding-right: 16rem; + } + + .ma0-m { margin: 0; } + .ma1-m { margin: .25rem; } + .ma2-m { margin: .5rem; } + .ma3-m { margin: 1rem; } + .ma4-m { margin: 2rem; } + .ma5-m { margin: 4rem; } + .ma6-m { margin: 8rem; } + .ma7-m { margin: 16rem; } + + .ml0-m { margin-left: 0; } + .ml1-m { margin-left: .25rem; } + .ml2-m { margin-left: .5rem; } + .ml3-m { margin-left: 1rem; } + .ml4-m { margin-left: 2rem; } + .ml5-m { margin-left: 4rem; } + .ml6-m { margin-left: 8rem; } + .ml7-m { margin-left: 16rem; } + + .mr0-m { margin-right: 0; } + .mr1-m { margin-right: .25rem; } + .mr2-m { margin-right: .5rem; } + .mr3-m { margin-right: 1rem; } + .mr4-m { margin-right: 2rem; } + .mr5-m { margin-right: 4rem; } + .mr6-m { margin-right: 8rem; } + .mr7-m { margin-right: 16rem; } + + .mb0-m { margin-bottom: 0; } + .mb1-m { margin-bottom: .25rem; } + .mb2-m { margin-bottom: .5rem; } + .mb3-m { margin-bottom: 1rem; } + .mb4-m { margin-bottom: 2rem; } + .mb5-m { margin-bottom: 4rem; } + .mb6-m { margin-bottom: 8rem; } + .mb7-m { margin-bottom: 16rem; } + + .mt0-m { margin-top: 0; } + .mt1-m { margin-top: .25rem; } + .mt2-m { margin-top: .5rem; } + .mt3-m { margin-top: 1rem; } + .mt4-m { margin-top: 2rem; } + .mt5-m { margin-top: 4rem; } + .mt6-m { margin-top: 8rem; } + .mt7-m { margin-top: 16rem; } + + .mv0-m { + margin-top: 0; + margin-bottom: 0; + } + .mv1-m { + margin-top: .25rem; + margin-bottom: .25rem; + } + .mv2-m { + margin-top: .5rem; + margin-bottom: .5rem; + } + .mv3-m { + margin-top: 1rem; + margin-bottom: 1rem; + } + .mv4-m { + margin-top: 2rem; + margin-bottom: 2rem; + } + .mv5-m { + margin-top: 4rem; + margin-bottom: 4rem; + } + .mv6-m { + margin-top: 8rem; + margin-bottom: 8rem; + } + .mv7-m { + margin-top: 16rem; + margin-bottom: 16rem; + } + + .mh0-m { + margin-left: 0; + margin-right: 0; + } + .mh1-m { + margin-left: .25rem; + margin-right: .25rem; + } + .mh2-m { + margin-left: .5rem; + margin-right: .5rem; + } + .mh3-m { + margin-left: 1rem; + margin-right: 1rem; + } + .mh4-m { + margin-left: 2rem; + margin-right: 2rem; + } + .mh5-m { + margin-left: 4rem; + margin-right: 4rem; + } + .mh6-m { + margin-left: 8rem; + margin-right: 8rem; + } + .mh7-m { + margin-left: 16rem; + margin-right: 16rem; + } + +} + +@media screen and (min-width: 60em) { + .pa0-l { padding: 0; } + .pa1-l { padding: .25rem; } + .pa2-l { padding: .5rem; } + .pa3-l { padding: 1rem; } + .pa4-l { padding: 2rem; } + .pa5-l { padding: 4rem; } + .pa6-l { padding: 8rem; } + .pa7-l { padding: 16rem; } + + .pl0-l { padding-left: 0; } + .pl1-l { padding-left: .25rem; } + .pl2-l { padding-left: .5rem; } + .pl3-l { padding-left: 1rem; } + .pl4-l { padding-left: 2rem; } + .pl5-l { padding-left: 4rem; } + .pl6-l { padding-left: 8rem; } + .pl7-l { padding-left: 16rem; } + + .pr0-l { padding-right: 0; } + .pr1-l { padding-right: .25rem; } + .pr2-l { padding-right: .5rem; } + .pr3-l { padding-right: 1rem; } + .pr4-l { padding-right: 2rem; } + .pr5-l { padding-right: 4rem; } + .pr6-l { padding-right: 8rem; } + .pr7-l { padding-right: 16rem; } + + .pb0-l { padding-bottom: 0; } + .pb1-l { padding-bottom: .25rem; } + .pb2-l { padding-bottom: .5rem; } + .pb3-l { padding-bottom: 1rem; } + .pb4-l { padding-bottom: 2rem; } + .pb5-l { padding-bottom: 4rem; } + .pb6-l { padding-bottom: 8rem; } + .pb7-l { padding-bottom: 16rem; } + + .pt0-l { padding-top: 0; } + .pt1-l { padding-top: .25rem; } + .pt2-l { padding-top: .5rem; } + .pt3-l { padding-top: 1rem; } + .pt4-l { padding-top: 2rem; } + .pt5-l { padding-top: 4rem; } + .pt6-l { padding-top: 8rem; } + .pt7-l { padding-top: 16rem; } + + .pv0-l { + padding-top: 0; + padding-bottom: 0; + } + .pv1-l { + padding-top: .25rem; + padding-bottom: .25rem; + } + .pv2-l { + padding-top: .5rem; + padding-bottom: .5rem; + } + .pv3-l { + padding-top: 1rem; + padding-bottom: 1rem; + } + .pv4-l { + padding-top: 2rem; + padding-bottom: 2rem; + } + .pv5-l { + padding-top: 4rem; + padding-bottom: 4rem; + } + .pv6-l { + padding-top: 8rem; + padding-bottom: 8rem; + } + .pv7-l { + padding-top: 16rem; + padding-bottom: 16rem; + } + + .ph0-l { + padding-left: 0; + padding-right: 0; + } + .ph1-l { + padding-left: .25rem; + padding-right: .25rem; + } + .ph2-l { + padding-left: .5rem; + padding-right: .5rem; + } + .ph3-l { + padding-left: 1rem; + padding-right: 1rem; + } + .ph4-l { + padding-left: 2rem; + padding-right: 2rem; + } + .ph5-l { + padding-left: 4rem; + padding-right: 4rem; + } + .ph6-l { + padding-left: 8rem; + padding-right: 8rem; + } + .ph7-l { + padding-left: 16rem; + padding-right: 16rem; + } + + .ma0-l { margin: 0; } + .ma1-l { margin: .25rem; } + .ma2-l { margin: .5rem; } + .ma3-l { margin: 1rem; } + .ma4-l { margin: 2rem; } + .ma5-l { margin: 4rem; } + .ma6-l { margin: 8rem; } + .ma7-l { margin: 16rem; } + + .ml0-l { margin-left: 0; } + .ml1-l { margin-left: .25rem; } + .ml2-l { margin-left: .5rem; } + .ml3-l { margin-left: 1rem; } + .ml4-l { margin-left: 2rem; } + .ml5-l { margin-left: 4rem; } + .ml6-l { margin-left: 8rem; } + .ml7-l { margin-left: 16rem; } + + .mr0-l { margin-right: 0; } + .mr1-l { margin-right: .25rem; } + .mr2-l { margin-right: .5rem; } + .mr3-l { margin-right: 1rem; } + .mr4-l { margin-right: 2rem; } + .mr5-l { margin-right: 4rem; } + .mr6-l { margin-right: 8rem; } + .mr7-l { margin-right: 16rem; } + + .mb0-l { margin-bottom: 0; } + .mb1-l { margin-bottom: .25rem; } + .mb2-l { margin-bottom: .5rem; } + .mb3-l { margin-bottom: 1rem; } + .mb4-l { margin-bottom: 2rem; } + .mb5-l { margin-bottom: 4rem; } + .mb6-l { margin-bottom: 8rem; } + .mb7-l { margin-bottom: 16rem; } + + .mt0-l { margin-top: 0; } + .mt1-l { margin-top: .25rem; } + .mt2-l { margin-top: .5rem; } + .mt3-l { margin-top: 1rem; } + .mt4-l { margin-top: 2rem; } + .mt5-l { margin-top: 4rem; } + .mt6-l { margin-top: 8rem; } + .mt7-l { margin-top: 16rem; } + + .mv0-l { + margin-top: 0; + margin-bottom: 0; + } + .mv1-l { + margin-top: .25rem; + margin-bottom: .25rem; + } + .mv2-l { + margin-top: .5rem; + margin-bottom: .5rem; + } + .mv3-l { + margin-top: 1rem; + margin-bottom: 1rem; + } + .mv4-l { + margin-top: 2rem; + margin-bottom: 2rem; + } + .mv5-l { + margin-top: 4rem; + margin-bottom: 4rem; + } + .mv6-l { + margin-top: 8rem; + margin-bottom: 8rem; + } + .mv7-l { + margin-top: 16rem; + margin-bottom: 16rem; + } + + .mh0-l { + margin-left: 0; + margin-right: 0; + } + .mh1-l { + margin-left: .25rem; + margin-right: .25rem; + } + .mh2-l { + margin-left: .5rem; + margin-right: .5rem; + } + .mh3-l { + margin-left: 1rem; + margin-right: 1rem; + } + .mh4-l { + margin-left: 2rem; + margin-right: 2rem; + } + .mh5-l { + margin-left: 4rem; + margin-right: 4rem; + } + .mh6-l { + margin-left: 8rem; + margin-right: 8rem; + } + .mh7-l { + margin-left: 16rem; + margin-right: 16rem; + } +} + +/* + NEGATIVE MARGINS + + Base: + n = negative + + Modifiers: + a = all + t = top + r = right + b = bottom + l = left + + 1 = 1st step in spacing scale + 2 = 2nd step in spacing scale + 3 = 3rd step in spacing scale + 4 = 4th step in spacing scale + 5 = 5th step in spacing scale + 6 = 6th step in spacing scale + 7 = 7th step in spacing scale + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.na1 { margin: -0.25rem; } + +.na2 { margin: -0.5rem; } + +.na3 { margin: -1rem; } + +.na4 { margin: -2rem; } + +.na5 { margin: -4rem; } + +.na6 { margin: -8rem; } + +.na7 { margin: -16rem; } + +.nl1 { margin-left: -0.25rem; } + +.nl2 { margin-left: -0.5rem; } + +.nl3 { margin-left: -1rem; } + +.nl4 { margin-left: -2rem; } + +.nl5 { margin-left: -4rem; } + +.nl6 { margin-left: -8rem; } + +.nl7 { margin-left: -16rem; } + +.nr1 { margin-right: -0.25rem; } + +.nr2 { margin-right: -0.5rem; } + +.nr3 { margin-right: -1rem; } + +.nr4 { margin-right: -2rem; } + +.nr5 { margin-right: -4rem; } + +.nr6 { margin-right: -8rem; } + +.nr7 { margin-right: -16rem; } + +.nb1 { margin-bottom: -0.25rem; } + +.nb2 { margin-bottom: -0.5rem; } + +.nb3 { margin-bottom: -1rem; } + +.nb4 { margin-bottom: -2rem; } + +.nb5 { margin-bottom: -4rem; } + +.nb6 { margin-bottom: -8rem; } + +.nb7 { margin-bottom: -16rem; } + +.nt1 { margin-top: -0.25rem; } + +.nt2 { margin-top: -0.5rem; } + +.nt3 { margin-top: -1rem; } + +.nt4 { margin-top: -2rem; } + +.nt5 { margin-top: -4rem; } + +.nt6 { margin-top: -8rem; } + +.nt7 { margin-top: -16rem; } + +@media screen and (min-width: 30em) { + + .na1-ns { margin: -0.25rem; } + .na2-ns { margin: -0.5rem; } + .na3-ns { margin: -1rem; } + .na4-ns { margin: -2rem; } + .na5-ns { margin: -4rem; } + .na6-ns { margin: -8rem; } + .na7-ns { margin: -16rem; } + + .nl1-ns { margin-left: -0.25rem; } + .nl2-ns { margin-left: -0.5rem; } + .nl3-ns { margin-left: -1rem; } + .nl4-ns { margin-left: -2rem; } + .nl5-ns { margin-left: -4rem; } + .nl6-ns { margin-left: -8rem; } + .nl7-ns { margin-left: -16rem; } + + .nr1-ns { margin-right: -0.25rem; } + .nr2-ns { margin-right: -0.5rem; } + .nr3-ns { margin-right: -1rem; } + .nr4-ns { margin-right: -2rem; } + .nr5-ns { margin-right: -4rem; } + .nr6-ns { margin-right: -8rem; } + .nr7-ns { margin-right: -16rem; } + + .nb1-ns { margin-bottom: -0.25rem; } + .nb2-ns { margin-bottom: -0.5rem; } + .nb3-ns { margin-bottom: -1rem; } + .nb4-ns { margin-bottom: -2rem; } + .nb5-ns { margin-bottom: -4rem; } + .nb6-ns { margin-bottom: -8rem; } + .nb7-ns { margin-bottom: -16rem; } + + .nt1-ns { margin-top: -0.25rem; } + .nt2-ns { margin-top: -0.5rem; } + .nt3-ns { margin-top: -1rem; } + .nt4-ns { margin-top: -2rem; } + .nt5-ns { margin-top: -4rem; } + .nt6-ns { margin-top: -8rem; } + .nt7-ns { margin-top: -16rem; } + +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .na1-m { margin: -0.25rem; } + .na2-m { margin: -0.5rem; } + .na3-m { margin: -1rem; } + .na4-m { margin: -2rem; } + .na5-m { margin: -4rem; } + .na6-m { margin: -8rem; } + .na7-m { margin: -16rem; } + + .nl1-m { margin-left: -0.25rem; } + .nl2-m { margin-left: -0.5rem; } + .nl3-m { margin-left: -1rem; } + .nl4-m { margin-left: -2rem; } + .nl5-m { margin-left: -4rem; } + .nl6-m { margin-left: -8rem; } + .nl7-m { margin-left: -16rem; } + + .nr1-m { margin-right: -0.25rem; } + .nr2-m { margin-right: -0.5rem; } + .nr3-m { margin-right: -1rem; } + .nr4-m { margin-right: -2rem; } + .nr5-m { margin-right: -4rem; } + .nr6-m { margin-right: -8rem; } + .nr7-m { margin-right: -16rem; } + + .nb1-m { margin-bottom: -0.25rem; } + .nb2-m { margin-bottom: -0.5rem; } + .nb3-m { margin-bottom: -1rem; } + .nb4-m { margin-bottom: -2rem; } + .nb5-m { margin-bottom: -4rem; } + .nb6-m { margin-bottom: -8rem; } + .nb7-m { margin-bottom: -16rem; } + + .nt1-m { margin-top: -0.25rem; } + .nt2-m { margin-top: -0.5rem; } + .nt3-m { margin-top: -1rem; } + .nt4-m { margin-top: -2rem; } + .nt5-m { margin-top: -4rem; } + .nt6-m { margin-top: -8rem; } + .nt7-m { margin-top: -16rem; } + +} + +@media screen and (min-width: 60em) { + .na1-l { margin: -0.25rem; } + .na2-l { margin: -0.5rem; } + .na3-l { margin: -1rem; } + .na4-l { margin: -2rem; } + .na5-l { margin: -4rem; } + .na6-l { margin: -8rem; } + .na7-l { margin: -16rem; } + + .nl1-l { margin-left: -0.25rem; } + .nl2-l { margin-left: -0.5rem; } + .nl3-l { margin-left: -1rem; } + .nl4-l { margin-left: -2rem; } + .nl5-l { margin-left: -4rem; } + .nl6-l { margin-left: -8rem; } + .nl7-l { margin-left: -16rem; } + + .nr1-l { margin-right: -0.25rem; } + .nr2-l { margin-right: -0.5rem; } + .nr3-l { margin-right: -1rem; } + .nr4-l { margin-right: -2rem; } + .nr5-l { margin-right: -4rem; } + .nr6-l { margin-right: -8rem; } + .nr7-l { margin-right: -16rem; } + + .nb1-l { margin-bottom: -0.25rem; } + .nb2-l { margin-bottom: -0.5rem; } + .nb3-l { margin-bottom: -1rem; } + .nb4-l { margin-bottom: -2rem; } + .nb5-l { margin-bottom: -4rem; } + .nb6-l { margin-bottom: -8rem; } + .nb7-l { margin-bottom: -16rem; } + + .nt1-l { margin-top: -0.25rem; } + .nt2-l { margin-top: -0.5rem; } + .nt3-l { margin-top: -1rem; } + .nt4-l { margin-top: -2rem; } + .nt5-l { margin-top: -4rem; } + .nt6-l { margin-top: -8rem; } + .nt7-l { margin-top: -16rem; } +} + +/* + + TABLES + Docs: http://tachyons.io/docs/elements/tables/ + +*/ + +.collapse { + border-collapse: collapse; + border-spacing: 0; +} + +.striped--light-silver:nth-child(odd) { + background-color: #aaa; +} + +.striped--moon-gray:nth-child(odd) { + background-color: #ccc; +} + +.striped--light-gray:nth-child(odd) { + background-color: #eee; +} + +.striped--near-white:nth-child(odd) { + background-color: #f4f4f4; +} + +.stripe-light:nth-child(odd) { + background-color: rgba(255, 255, 255, .1); +} + +.stripe-dark:nth-child(odd) { + background-color: rgba(0, 0, 0, .1); +} + +/* + + TEXT DECORATION + Docs: http://tachyons.io/docs/typography/text-decoration/ + + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.strike { text-decoration: line-through; } + +.underline { text-decoration: underline; } + +.no-underline { text-decoration: none; } + +@media screen and (min-width: 30em) { + .strike-ns { text-decoration: line-through; } + .underline-ns { text-decoration: underline; } + .no-underline-ns { text-decoration: none; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .strike-m { text-decoration: line-through; } + .underline-m { text-decoration: underline; } + .no-underline-m { text-decoration: none; } +} + +@media screen and (min-width: 60em) { + .strike-l { text-decoration: line-through; } + .underline-l { text-decoration: underline; } + .no-underline-l { text-decoration: none; } +} + +/* + + TEXT ALIGN + Docs: http://tachyons.io/docs/typography/text-align/ + + Base + t = text-align + + Modifiers + l = left + r = right + c = center + j = justify + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.tl { text-align: left; } + +.tr { text-align: right; } + +.tc { text-align: center; } + +.tj { text-align: justify; } + +@media screen and (min-width: 30em) { + .tl-ns { text-align: left; } + .tr-ns { text-align: right; } + .tc-ns { text-align: center; } + .tj-ns { text-align: justify; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .tl-m { text-align: left; } + .tr-m { text-align: right; } + .tc-m { text-align: center; } + .tj-m { text-align: justify; } +} + +@media screen and (min-width: 60em) { + .tl-l { text-align: left; } + .tr-l { text-align: right; } + .tc-l { text-align: center; } + .tj-l { text-align: justify; } +} + +/* + + TEXT TRANSFORM + Docs: http://tachyons.io/docs/typography/text-transform/ + + Base: + tt = text-transform + + Modifiers + c = capitalize + l = lowercase + u = uppercase + n = none + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.ttc { text-transform: capitalize; } + +.ttl { text-transform: lowercase; } + +.ttu { text-transform: uppercase; } + +.ttn { text-transform: none; } + +@media screen and (min-width: 30em) { + .ttc-ns { text-transform: capitalize; } + .ttl-ns { text-transform: lowercase; } + .ttu-ns { text-transform: uppercase; } + .ttn-ns { text-transform: none; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .ttc-m { text-transform: capitalize; } + .ttl-m { text-transform: lowercase; } + .ttu-m { text-transform: uppercase; } + .ttn-m { text-transform: none; } +} + +@media screen and (min-width: 60em) { + .ttc-l { text-transform: capitalize; } + .ttl-l { text-transform: lowercase; } + .ttu-l { text-transform: uppercase; } + .ttn-l { text-transform: none; } +} + +/* + + TYPE SCALE + Docs: http://tachyons.io/docs/typography/scale/ + + Base: + f = font-size + + Modifiers + 1 = 1st step in size scale + 2 = 2nd step in size scale + 3 = 3rd step in size scale + 4 = 4th step in size scale + 5 = 5th step in size scale + 6 = 6th step in size scale + 7 = 7th step in size scale + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large +*/ + +/* + * For Hero/Marketing Titles + * + * These generally are too large for mobile + * so be careful using them on smaller screens. + * */ + +.f-6, +.f-headline { + font-size: 6rem; +} + +.f-5, +.f-subheadline { + font-size: 5rem; +} + +/* Type Scale */ + +.f1 { font-size: 3rem; } + +.f2 { font-size: 2.25rem; } + +.f3 { font-size: 1.5rem; } + +.f4 { font-size: 1.25rem; } + +.f5 { font-size: 1rem; } + +.f6 { font-size: .875rem; } + +.f7 { font-size: .75rem; } + +/* Small and hard to read for many people so use with extreme caution */ + +@media screen and (min-width: 30em){ + .f-6-ns, + .f-headline-ns { font-size: 6rem; } + .f-5-ns, + .f-subheadline-ns { font-size: 5rem; } + .f1-ns { font-size: 3rem; } + .f2-ns { font-size: 2.25rem; } + .f3-ns { font-size: 1.5rem; } + .f4-ns { font-size: 1.25rem; } + .f5-ns { font-size: 1rem; } + .f6-ns { font-size: .875rem; } + .f7-ns { font-size: .75rem; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .f-6-m, + .f-headline-m { font-size: 6rem; } + .f-5-m, + .f-subheadline-m { font-size: 5rem; } + .f1-m { font-size: 3rem; } + .f2-m { font-size: 2.25rem; } + .f3-m { font-size: 1.5rem; } + .f4-m { font-size: 1.25rem; } + .f5-m { font-size: 1rem; } + .f6-m { font-size: .875rem; } + .f7-m { font-size: .75rem; } +} + +@media screen and (min-width: 60em) { + .f-6-l, + .f-headline-l { + font-size: 6rem; + } + .f-5-l, + .f-subheadline-l { + font-size: 5rem; + } + .f1-l { font-size: 3rem; } + .f2-l { font-size: 2.25rem; } + .f3-l { font-size: 1.5rem; } + .f4-l { font-size: 1.25rem; } + .f5-l { font-size: 1rem; } + .f6-l { font-size: .875rem; } + .f7-l { font-size: .75rem; } +} + +/* + + TYPOGRAPHY + http://tachyons.io/docs/typography/measure/ + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +/* Measure is limited to ~66 characters */ + +.measure { + max-width: 30em; +} + +/* Measure is limited to ~80 characters */ + +.measure-wide { + max-width: 34em; +} + +/* Measure is limited to ~45 characters */ + +.measure-narrow { + max-width: 20em; +} + +/* Book paragraph style - paragraphs are indented with no vertical spacing. */ + +.indent { + text-indent: 1em; + margin-top: 0; + margin-bottom: 0; +} + +.small-caps { + -webkit-font-feature-settings: "c2sc"; + font-feature-settings: "c2sc"; + font-variant: small-caps; +} + +/* Combine this class with a width to truncate text (or just leave as is to truncate at width of containing element. */ + +.truncate { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +@media screen and (min-width: 30em) { + .measure-ns { + max-width: 30em; + } + .measure-wide-ns { + max-width: 34em; + } + .measure-narrow-ns { + max-width: 20em; + } + .indent-ns { + text-indent: 1em; + margin-top: 0; + margin-bottom: 0; + } + .small-caps-ns { + -webkit-font-feature-settings: "c2sc"; + font-feature-settings: "c2sc"; + font-variant: small-caps; + } + .truncate-ns { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .measure-m { + max-width: 30em; + } + .measure-wide-m { + max-width: 34em; + } + .measure-narrow-m { + max-width: 20em; + } + .indent-m { + text-indent: 1em; + margin-top: 0; + margin-bottom: 0; + } + .small-caps-m { + -webkit-font-feature-settings: "c2sc"; + font-feature-settings: "c2sc"; + font-variant: small-caps; + } + .truncate-m { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +} + +@media screen and (min-width: 60em) { + .measure-l { + max-width: 30em; + } + .measure-wide-l { + max-width: 34em; + } + .measure-narrow-l { + max-width: 20em; + } + .indent-l { + text-indent: 1em; + margin-top: 0; + margin-bottom: 0; + } + .small-caps-l { + -webkit-font-feature-settings: "c2sc"; + font-feature-settings: "c2sc"; + font-variant: small-caps; + } + .truncate-l { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +} + +/* + + UTILITIES + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +/* Equivalent to .overflow-y-scroll */ + +.overflow-container { + overflow-y: scroll; +} + +.center { + margin-right: auto; + margin-left: auto; +} + +.mr-auto { margin-right: auto; } + +.ml-auto { margin-left: auto; } + +@media screen and (min-width: 30em){ + .center-ns { + margin-right: auto; + margin-left: auto; + } + .mr-auto-ns { margin-right: auto; } + .ml-auto-ns { margin-left: auto; } +} + +@media screen and (min-width: 30em) and (max-width: 60em){ + .center-m { + margin-right: auto; + margin-left: auto; + } + .mr-auto-m { margin-right: auto; } + .ml-auto-m { margin-left: auto; } +} + +@media screen and (min-width: 60em){ + .center-l { + margin-right: auto; + margin-left: auto; + } + .mr-auto-l { margin-right: auto; } + .ml-auto-l { margin-left: auto; } +} + +/* + + VISIBILITY + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +/* + Text that is hidden but accessible + Ref: http://snook.ca/archives/html_and_css/hiding-content-for-accessibility +*/ + +.clip { + position: fixed !important; + _position: absolute !important; + clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ + clip: rect(1px, 1px, 1px, 1px); +} + +@media screen and (min-width: 30em) { + .clip-ns { + position: fixed !important; + _position: absolute !important; + clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ + clip: rect(1px, 1px, 1px, 1px); + } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .clip-m { + position: fixed !important; + _position: absolute !important; + clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ + clip: rect(1px, 1px, 1px, 1px); + } +} + +@media screen and (min-width: 60em) { + .clip-l { + position: fixed !important; + _position: absolute !important; + clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ + clip: rect(1px, 1px, 1px, 1px); + } +} + +/* + + WHITE SPACE + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.ws-normal { white-space: normal; } + +.nowrap { white-space: nowrap; } + +.pre { white-space: pre; } + +@media screen and (min-width: 30em) { + .ws-normal-ns { white-space: normal; } + .nowrap-ns { white-space: nowrap; } + .pre-ns { white-space: pre; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .ws-normal-m { white-space: normal; } + .nowrap-m { white-space: nowrap; } + .pre-m { white-space: pre; } +} + +@media screen and (min-width: 60em) { + .ws-normal-l { white-space: normal; } + .nowrap-l { white-space: nowrap; } + .pre-l { white-space: pre; } +} + +/* + + VERTICAL ALIGN + + Media Query Extensions: + -ns = not-small + -m = medium + -l = large + +*/ + +.v-base { vertical-align: baseline; } + +.v-mid { vertical-align: middle; } + +.v-top { vertical-align: top; } + +.v-btm { vertical-align: bottom; } + +@media screen and (min-width: 30em) { + .v-base-ns { vertical-align: baseline; } + .v-mid-ns { vertical-align: middle; } + .v-top-ns { vertical-align: top; } + .v-btm-ns { vertical-align: bottom; } +} + +@media screen and (min-width: 30em) and (max-width: 60em) { + .v-base-m { vertical-align: baseline; } + .v-mid-m { vertical-align: middle; } + .v-top-m { vertical-align: top; } + .v-btm-m { vertical-align: bottom; } +} + +@media screen and (min-width: 60em) { + .v-base-l { vertical-align: baseline; } + .v-mid-l { vertical-align: middle; } + .v-top-l { vertical-align: top; } + .v-btm-l { vertical-align: bottom; } +} + +/* + + HOVER EFFECTS + Docs: http://tachyons.io/docs/themes/hovers/ + + - Dim + - Glow + - Hide Child + - Underline text + - Grow + - Pointer + - Shadow + +*/ + +/* + + Dim element on hover by adding the dim class. + +*/ + +.dim { + opacity: 1; + transition: opacity .15s ease-in; +} + +.dim:hover, +.dim:focus { + opacity: .5; + transition: opacity .15s ease-in; +} + +.dim:active { + opacity: .8; transition: opacity .15s ease-out; +} + +/* + + Animate opacity to 100% on hover by adding the glow class. + +*/ + +.glow { + transition: opacity .15s ease-in; +} + +.glow:hover, +.glow:focus { + opacity: 1; + transition: opacity .15s ease-in; +} + +/* + + Hide child & reveal on hover: + + Put the hide-child class on a parent element and any nested element with the + child class will be hidden and displayed on hover or focus. + +
+
Hidden until hover or focus
+
Hidden until hover or focus
+
Hidden until hover or focus
+
Hidden until hover or focus
+
+*/ + +.hide-child .child { + opacity: 0; + transition: opacity .15s ease-in; +} + +.hide-child:hover .child, +.hide-child:focus .child, +.hide-child:active .child { + opacity: 1; + transition: opacity .15s ease-in; +} + +.underline-hover:hover, +.underline-hover:focus { + text-decoration: underline; +} + +/* Can combine this with overflow-hidden to make background images grow on hover + * even if you are using background-size: cover */ + +.grow { + -moz-osx-font-smoothing: grayscale; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-transform: translateZ(0); + transform: translateZ(0); + transition: -webkit-transform 0.25s ease-out; + transition: transform 0.25s ease-out; + transition: transform 0.25s ease-out, -webkit-transform 0.25s ease-out; +} + +.grow:hover, +.grow:focus { + -webkit-transform: scale(1.05); + transform: scale(1.05); +} + +.grow:active { + -webkit-transform: scale(.90); + transform: scale(.90); +} + +.grow-large { + -moz-osx-font-smoothing: grayscale; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-transform: translateZ(0); + transform: translateZ(0); + transition: -webkit-transform .25s ease-in-out; + transition: transform .25s ease-in-out; + transition: transform .25s ease-in-out, -webkit-transform .25s ease-in-out; +} + +.grow-large:hover, +.grow-large:focus { + -webkit-transform: scale(1.2); + transform: scale(1.2); +} + +.grow-large:active { + -webkit-transform: scale(.95); + transform: scale(.95); +} + +/* Add pointer on hover */ + +.pointer:hover { + cursor: pointer; +} + +/* + Add shadow on hover. + + Performant box-shadow animation pattern from + http://tobiasahlin.com/blog/how-to-animate-box-shadow/ +*/ + +.shadow-hover { + cursor: pointer; + position: relative; + transition: all 0.5s cubic-bezier(0.165, 0.84, 0.44, 1); +} + +.shadow-hover::after { + content: ''; + box-shadow: 0px 0px 16px 2px rgba(0, 0, 0, .2); + border-radius: inherit; + opacity: 0; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: -1; + transition: opacity 0.5s cubic-bezier(0.165, 0.84, 0.44, 1); +} + +.shadow-hover:hover::after, +.shadow-hover:focus::after { + opacity: 1; +} + +/* Combine with classes in skins and skins-pseudo for + * many different transition possibilities. */ + +.bg-animate, +.bg-animate:hover, +.bg-animate:focus { + transition: background-color .15s ease-in-out; +} + +/* + + Z-INDEX + + Base + z = z-index + + Modifiers + -0 = literal value 0 + -1 = literal value 1 + -2 = literal value 2 + -3 = literal value 3 + -4 = literal value 4 + -5 = literal value 5 + -999 = literal value 999 + -9999 = literal value 9999 + + -max = largest accepted z-index value as integer + + -inherit = string value inherit + -initial = string value initial + -unset = string value unset + + MDN: https://developer.mozilla.org/en/docs/Web/CSS/z-index + Spec: http://www.w3.org/TR/CSS2/zindex.html + Articles: + https://philipwalton.com/articles/what-no-one-told-you-about-z-index/ + + Tips on extending: + There might be a time worth using negative z-index values. + Or if you are using tachyons with another project, you might need to + adjust these values to suit your needs. + +*/ + +.z-0 { z-index: 0; } + +.z-1 { z-index: 1; } + +.z-2 { z-index: 2; } + +.z-3 { z-index: 3; } + +.z-4 { z-index: 4; } + +.z-5 { z-index: 5; } + +.z-999 { z-index: 999; } + +.z-9999 { z-index: 9999; } + +.z-max { + z-index: 2147483647; +} + +.z-inherit { z-index: inherit; } + +.z-initial { z-index: auto; z-index: initial; } + +.z-unset { z-index: unset; } + +/* + + NESTED + Tachyons module for styling nested elements + that are generated by a cms. + +*/ + +.nested-copy-line-height p, +.nested-copy-line-height ul, +.nested-copy-line-height ol { + line-height: 1.5; +} + +.nested-headline-line-height h1, +.nested-headline-line-height h2, +.nested-headline-line-height h3, +.nested-headline-line-height h4, +.nested-headline-line-height h5, +.nested-headline-line-height h6 { + line-height: 1.25; +} + +.nested-list-reset ul, +.nested-list-reset ol { + padding-left: 0; + margin-left: 0; + list-style-type: none; +} + +.nested-copy-indent p+p { + text-indent: 1em; + margin-top: 0; + margin-bottom: 0; +} + +.nested-copy-separator p+p { + margin-top: 1.5em; +} + +.nested-img img { + width: 100%; + max-width: 100%; + display: block; +} + +.nested-links a { + color: #357edd; + transition: color .15s ease-in; +} + +.nested-links a:hover, +.nested-links a:focus { + color: #96ccff; + transition: color .15s ease-in; +} + +/* + + STYLES + + Add custom styles here. + +*/ + +/* Variables */ + +/* Importing here will allow you to override any variables in the modules */ + +/* + + Tachyons + COLOR VARIABLES + + Grayscale + - Solids + - Transparencies + Colors + +*/ + +/* + + CUSTOM MEDIA QUERIES + + Media query values can be changed to fit your own content. + There are no magic bullets when it comes to media query width values. + They should be declared in em units - and they should be set to meet + the needs of your content. You can also add additional media queries, + or remove some of the existing ones. + + These media queries can be referenced like so: + + @media (--breakpoint-not-small) { + .medium-and-larger-specific-style { + background-color: red; + } + } + + @media (--breakpoint-medium) { + .medium-screen-specific-style { + background-color: red; + } + } + + @media (--breakpoint-large) { + .large-and-larger-screen-specific-style { + background-color: red; + } + } + +*/ + +/* Media Queries */ + +/* Debugging */ + +/* @import 'tachyons/src/_debug-children'; +@import 'tachyons/src/_debug-grid'; */ + +/* Uncomment out the line below to help debug layout issues */ + +/* @import 'tachyons/src/_debug'; */ + +pre, .pre { + overflow-x: auto; + overflow-y: hidden; + overflow: scroll; +} + +pre code { + display: block; + padding: 1.5em 1.5em; + white-space: pre; + font-size: .875rem; + line-height: 2; + +} + +pre { + background-color: #222; + color: #ddd; + white-space: pre; + + -webkit-hyphens: none; + + -ms-hyphens: none; + + hyphens: none; + position: relative; +} + +/* pagination.html: https://github.com/spf13/hugo/blob/master/tpl/tplimpl/template_embedded.go#L117 */ + +.pagination { + margin: 3rem 0; +} + +.pagination li { + display: inline-block; + margin-right: .375rem; + font-size: .875rem; + margin-bottom: 2.5em; +} + +.pagination li a { + padding: .5rem .625rem; + background-color: white; + color: #333; + border: 1px solid #ddd; + border-radius: 3px; + text-decoration: none; +} + +.pagination li.disabled { + display: none; +} + +.pagination li.active a:link, +.pagination li.active a:active, +.pagination li.active a:visited { + background-color: #ddd; +} + +#TableOfContents ul li { + margin-bottom: 1em; +} + +.facebook, .twitter, .instagram, .youtube, .github, .gitlab, .keybase, .linkedin, .medium, .mastodon, .slack, .stackoverflow, .rss { + fill: #BABABA; +} + +.new-window { + opacity: 0; + display: inline-block; + vertical-align: top; +} + +.link-transition:hover .new-window{ + opacity: 1; +} + +.facebook:hover { + fill: #3b5998; +} + +.twitter:hover { + fill: #1da1f2; +} + +.instagram:hover { + fill: #e1306c; +} + +.youtube:hover { + fill: #cd201f; +} + +.github:hover { + fill: #6cc644; +} + +.gitlab:hover { + fill: #FC6D26; +} + +.keybase:hover { + fill: #3d76ff; +} + +.linkedin:hover { + fill: #0077b5 +} + +.medium:hover { + fill: #0077b5 +} + +.mastodon:hover { + fill: #3088d4; +} + +.slack:hover { + fill: #E01E5A; +} + +.stackoverflow:hover { + fill: #f48024; +} + +.rss:hover{ + fill: #ff6f1a; +} + +/* Put your custom styles here and run `npm start` from the "src" directory on */ + +#TableOfContents ul li { + margin-bottom: 1em; +} + +.lh-copy blockquote { + display: block; + font-size: .875em; + margin-left: 2rem; + margin-top: 2rem; + margin-bottom: 2rem; + border-left: 4px solid #ccc; + padding-left: 1rem; + +} diff --git a/public/dist/js/app.3fc0f988d21662902933.js b/public/dist/js/app.3fc0f988d21662902933.js new file mode 100644 index 00000000..ad6c35c3 --- /dev/null +++ b/public/dist/js/app.3fc0f988d21662902933.js @@ -0,0 +1 @@ +!function(n){function t(e){if(r[e])return r[e].exports;var o=r[e]={i:e,l:!1,exports:{}};return n[e].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var r={};t.m=n,t.c=r,t.i=function(n){return n},t.d=function(n,r,e){t.o(n,r)||Object.defineProperty(n,r,{configurable:!1,enumerable:!0,get:e})},t.n=function(n){var r=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(r,"a",r),r},t.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},t.p="",t(t.s=1)}([function(n,t){},function(n,t,r){"use strict";var e=r(0);!function(n){n&&n.__esModule}(e)}]); \ No newline at end of file diff --git a/public/events/2017_07_arctic/index.html b/public/events/2017_07_arctic/index.html new file mode 100644 index 00000000..7dea1971 --- /dev/null +++ b/public/events/2017_07_arctic/index.html @@ -0,0 +1,335 @@ + + + + + + + Tools for Data Science in Arctic Research (July 2017) | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Tools for Data Science in Arctic Research (July 2017) +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2017_07_oss/index.html b/public/events/2017_07_oss/index.html new file mode 100644 index 00000000..b7c87354 --- /dev/null +++ b/public/events/2017_07_oss/index.html @@ -0,0 +1,231 @@ + + + + + + + Open Science for Synthesis: Gulf Research Program Workshop | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Open Science for Synthesis: Gulf Research Program Workshop +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2018_06_arctic/index.html b/public/events/2018_06_arctic/index.html new file mode 100644 index 00000000..6c8ffb17 --- /dev/null +++ b/public/events/2018_06_arctic/index.html @@ -0,0 +1,253 @@ + + + + + + + Dataset Publishing with the Arctic Data Center (June 2018) | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Dataset Publishing with the Arctic Data Center (June 2018) +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2018_08_arctic/index.html b/public/events/2018_08_arctic/index.html new file mode 100644 index 00000000..a46d1610 --- /dev/null +++ b/public/events/2018_08_arctic/index.html @@ -0,0 +1,459 @@ + + + + + + + Arctic Data Center Training (August 2018) | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Arctic Data Center Training (August 2018) +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2019_01_arctic/index.html b/public/events/2019_01_arctic/index.html new file mode 100644 index 00000000..a33ff328 --- /dev/null +++ b/public/events/2019_01_arctic/index.html @@ -0,0 +1,486 @@ + + + + + + + Arctic Data Center Training (January 2019) | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Arctic Data Center Training (January 2019) +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2019_01_openscapes/index.html b/public/events/2019_01_openscapes/index.html new file mode 100644 index 00000000..e15eea73 --- /dev/null +++ b/public/events/2019_01_openscapes/index.html @@ -0,0 +1,215 @@ + + + + + + + Openscapes Champions Cohort sponsored by Mozilla | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Openscapes Champions Cohort sponsored by Mozilla +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2019_02_arctic/index.html b/public/events/2019_02_arctic/index.html new file mode 100644 index 00000000..7886d842 --- /dev/null +++ b/public/events/2019_02_arctic/index.html @@ -0,0 +1,463 @@ + + + + + + + Arctic Data Center Training (February 2019) | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Arctic Data Center Training (February 2019) +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2019_10_arctic/index.html b/public/events/2019_10_arctic/index.html new file mode 100644 index 00000000..98569abf --- /dev/null +++ b/public/events/2019_10_arctic/index.html @@ -0,0 +1,439 @@ + + + + + + + Arctic Data Center Training (October 2019) | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Arctic Data Center Training (October 2019) +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2019_11_nceas/index.html b/public/events/2019_11_nceas/index.html new file mode 100644 index 00000000..e7864a71 --- /dev/null +++ b/public/events/2019_11_nceas/index.html @@ -0,0 +1,331 @@ + + + + + + + Reproducible Research Techniques for Synthesis (November 2019) | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Reproducible Research Techniques for Synthesis (November 2019) +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2020_02_nceas/index.html b/public/events/2020_02_nceas/index.html new file mode 100644 index 00000000..107f5989 --- /dev/null +++ b/public/events/2020_02_nceas/index.html @@ -0,0 +1,331 @@ + + + + + + + Reproducible Research Techniques for Synthesis (February 2020) | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Reproducible Research Techniques for Synthesis (February 2020) +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2020_02_openscapes/index.html b/public/events/2020_02_openscapes/index.html new file mode 100644 index 00000000..94911100 --- /dev/null +++ b/public/events/2020_02_openscapes/index.html @@ -0,0 +1,215 @@ + + + + + + + Openscapes Champions Workshop with NOAA | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Openscapes Champions Workshop with NOAA +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2020_02_snapp/index.html b/public/events/2020_02_snapp/index.html new file mode 100644 index 00000000..6d3e6bf7 --- /dev/null +++ b/public/events/2020_02_snapp/index.html @@ -0,0 +1,328 @@ + + + + + + + Data Science and Collaboration Skills for Integrative Conservation Science | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Data Science and Collaboration Skills for Integrative Conservation Science +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2020_04_nceaswg/index.html b/public/events/2020_04_nceaswg/index.html new file mode 100644 index 00000000..b77f5a8c --- /dev/null +++ b/public/events/2020_04_nceaswg/index.html @@ -0,0 +1,205 @@ + + + + + + + Efficient virtual collaboration & facilitation for synthesis science | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Efficient virtual collaboration & facilitation for synthesis science +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2020_05_nceaswg/index.html b/public/events/2020_05_nceaswg/index.html new file mode 100644 index 00000000..738fd2a9 --- /dev/null +++ b/public/events/2020_05_nceaswg/index.html @@ -0,0 +1,262 @@ + + + + + + + Tools and practices for collaborative, reproducible data science | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Tools and practices for collaborative, reproducible data science +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2020_10_arctic/index.html b/public/events/2020_10_arctic/index.html new file mode 100644 index 00000000..dd536352 --- /dev/null +++ b/public/events/2020_10_arctic/index.html @@ -0,0 +1,339 @@ + + + + + + + Arctic Data Center Training (October 2020) | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Arctic Data Center Training (October 2020) +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2020_11_nceas/index.html b/public/events/2020_11_nceas/index.html new file mode 100644 index 00000000..214d4e22 --- /dev/null +++ b/public/events/2020_11_nceas/index.html @@ -0,0 +1,341 @@ + + + + + + + Reproducible Research Techniques for Synthesis (November 2020) | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Reproducible Research Techniques for Synthesis (November 2020) +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2020_12_neon/index.html b/public/events/2020_12_neon/index.html new file mode 100644 index 00000000..44280c91 --- /dev/null +++ b/public/events/2020_12_neon/index.html @@ -0,0 +1,211 @@ + + + + + + + NEON Onboarding | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ NEON Onboarding +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2021_02_nceas/index.html b/public/events/2021_02_nceas/index.html new file mode 100644 index 00000000..205bb44d --- /dev/null +++ b/public/events/2021_02_nceas/index.html @@ -0,0 +1,341 @@ + + + + + + + Reproducible Research Techniques for Synthesis (February 2021) | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Reproducible Research Techniques for Synthesis (February 2021) +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2021_07_nceas/index.html b/public/events/2021_07_nceas/index.html new file mode 100644 index 00000000..d34c3800 --- /dev/null +++ b/public/events/2021_07_nceas/index.html @@ -0,0 +1,341 @@ + + + + + + + Reproducible Research Techniques for Synthesis (July 2021) | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Reproducible Research Techniques for Synthesis (July 2021) +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2021_08_esa/index.html b/public/events/2021_08_esa/index.html new file mode 100644 index 00000000..da68e7ef --- /dev/null +++ b/public/events/2021_08_esa/index.html @@ -0,0 +1,222 @@ + + + + + + + Managing Ecological Data for Effective Use and Re-Use | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Managing Ecological Data for Effective Use and Re-Use +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2021_09_delta/DSP_Logo_Horizontal.jpg b/public/events/2021_09_delta/DSP_Logo_Horizontal.jpg new file mode 100644 index 00000000..6f4a7978 Binary files /dev/null and b/public/events/2021_09_delta/DSP_Logo_Horizontal.jpg differ diff --git a/public/events/2021_09_delta/index.html b/public/events/2021_09_delta/index.html new file mode 100644 index 00000000..caebed01 --- /dev/null +++ b/public/events/2021_09_delta/index.html @@ -0,0 +1,271 @@ + + + + + + + Open Science Synthesis for the Delta Science Program | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Open Science Synthesis for the Delta Science Program +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2021_11_nceas/index.html b/public/events/2021_11_nceas/index.html new file mode 100644 index 00000000..5a29d80f --- /dev/null +++ b/public/events/2021_11_nceas/index.html @@ -0,0 +1,345 @@ + + + + + + + Reproducible Research Techniques for Synthesis (November 2021) | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Reproducible Research Techniques for Synthesis (November 2021) +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2022-04-arctic/index.html b/public/events/2022-04-arctic/index.html new file mode 100644 index 00000000..497d0919 --- /dev/null +++ b/public/events/2022-04-arctic/index.html @@ -0,0 +1,262 @@ + + + + + + + Fundamentals in Data Management for Qualitative and Quantitative Arctic Research | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Fundamentals in Data Management for Qualitative and Quantitative Arctic Research +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2022-09-arctic/index.html b/public/events/2022-09-arctic/index.html new file mode 100644 index 00000000..3a8461cb --- /dev/null +++ b/public/events/2022-09-arctic/index.html @@ -0,0 +1,277 @@ + + + + + + + Scalable and Computationally Reproducible Approaches to Arctic Research | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Scalable and Computationally Reproducible Approaches to Arctic Research +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2022_02_arctic/index.html b/public/events/2022_02_arctic/index.html new file mode 100644 index 00000000..d6f30cf4 --- /dev/null +++ b/public/events/2022_02_arctic/index.html @@ -0,0 +1,267 @@ + + + + + + + Arctic Data Center Training (February 2022) | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Arctic Data Center Training (February 2022) +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2022_03_arctic/index.html b/public/events/2022_03_arctic/index.html new file mode 100644 index 00000000..539a90f9 --- /dev/null +++ b/public/events/2022_03_arctic/index.html @@ -0,0 +1,256 @@ + + + + + + + Open Science: Best Practices, Data Sovereignty and Co-production | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Open Science: Best Practices, Data Sovereignty and Co-production +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2023-01-arctic/index.html b/public/events/2023-01-arctic/index.html new file mode 100644 index 00000000..f37e1451 --- /dev/null +++ b/public/events/2023-01-arctic/index.html @@ -0,0 +1,267 @@ + + + + + + + Fundamentals in Data Management for Qualitative and Quantitative Arctic Research | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Fundamentals in Data Management for Qualitative and Quantitative Arctic Research +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2023-02-arctic/index.html b/public/events/2023-02-arctic/index.html new file mode 100644 index 00000000..d71517d8 --- /dev/null +++ b/public/events/2023-02-arctic/index.html @@ -0,0 +1,276 @@ + + + + + + + Reproducible Practices for Arctic Research Using R | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Reproducible Practices for Arctic Research Using R +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2023-03-arctic/index.html b/public/events/2023-03-arctic/index.html new file mode 100644 index 00000000..7c91eebd --- /dev/null +++ b/public/events/2023-03-arctic/index.html @@ -0,0 +1,262 @@ + + + + + + + Scalable and Computationally Reproducible Approaches to Arctic Research | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Scalable and Computationally Reproducible Approaches to Arctic Research +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2023-04-corer/index.html b/public/events/2023-04-corer/index.html new file mode 100644 index 00000000..8a807d5b --- /dev/null +++ b/public/events/2023-04-corer/index.html @@ -0,0 +1,267 @@ + + + + + + + NCEAS Learning Hub coreR Course | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ NCEAS Learning Hub coreR Course +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/2023-06-delta/index.html b/public/events/2023-06-delta/index.html new file mode 100644 index 00000000..51aa4265 --- /dev/null +++ b/public/events/2023-06-delta/index.html @@ -0,0 +1,256 @@ + + + + + + + Open Science Synthesis for the Delta Science Program | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+ +
+
+ + + +
+
+
+

+ EVENTS +

+

+ Open Science Synthesis for the Delta Science Program +

+
+ +
+
+ +
+ + + + + + + + + diff --git a/public/events/index.html b/public/events/index.html new file mode 100644 index 00000000..2d33fb46 --- /dev/null +++ b/public/events/index.html @@ -0,0 +1,413 @@ + + + + + + + NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+

+ Events +

+ +
+
+
+ + +
+ +
+
+
+ +
+
+

+ + Open Science Synthesis for the Delta Science Program + +

+ +
+
+
+ +
+
+

+ + NCEAS Learning Hub coreR Course + +

+ +
+
+
+ +
+
+

+ + Scalable and Computationally Reproducible Approaches to Arctic Research + +

+ +
+
+
+ +
+
+

+ + Reproducible Practices for Arctic Research Using R + +

+ +
+
+
+ +
+
+

+ + Fundamentals in Data Management for Qualitative and Quantitative Arctic Research + +

+ +
+
+
+ +
+
+

+ + Scalable and Computationally Reproducible Approaches to Arctic Research + +

+ +
+
+
+ +
+
+

+ + Fundamentals in Data Management for Qualitative and Quantitative Arctic Research + +

+ +
+
+
+ +
+
+

+ + Arctic Data Center Training (February 2022) + +

+ +
+
+
+ +
+
+

+ + Open Science: Best Practices, Data Sovereignty and Co-production + +

+ +
+
+
+ +
+
+

+ + Reproducible Research Techniques for Synthesis (November 2021) + +

+ +
+
+
+ +
+ + + +
+ +
+ + + + + + + + + diff --git a/public/events/index.xml b/public/events/index.xml new file mode 100644 index 00000000..09a40598 --- /dev/null +++ b/public/events/index.xml @@ -0,0 +1,360 @@ + + + + Events on NCEAS Training Materials Catalog + /events/ + Recent content in Events on NCEAS Training Materials Catalog + Hugo -- gohugo.io + en-us + Mon, 26 Jun 2023 00:00:00 +0000 + + + + + + Open Science Synthesis for the Delta Science Program + /events/2023-06-delta/ + Mon, 26 Jun 2023 00:00:00 +0000 + + /events/2023-06-delta/ + In collaboration with the Delta Science Program we are running a 12 month facilitated research synthesis activity, supported by 3 one-week intensive training events. Curriculum material will focus on introducing Delta Researchers to best practices in, and application of, scientific computing and scientific software for reproducible science. In addition to developing and delivering learning curriculum, this collaboration will include the provision of data consulting, synthesis facilitation, and a remote workshop to conclude the group synthesis activities. + + + + NCEAS Learning Hub coreR Course + /events/2023-04-corer/ + Mon, 03 Apr 2023 00:00:00 +0000 + + /events/2023-04-corer/ + Previously called the Reproducible Research Techniques for Synthesis course +Dates: April 3-7, 2023 +Location: NCEAS Venue: Santa Barbara, CA +A five-day immersion in R programming for environmental data science. Researchers will gain experience with essential data science tools and best practices to increase their capacity as collaborators, reproducible coders, and open scientists. This course is taught both in-person and virtually. +Materials Link to course book +Instructors Name Email Halina Do-Linh dolinh@nceas. + + + + Scalable and Computationally Reproducible Approaches to Arctic Research + /events/2023-03-arctic/ + Thu, 23 Mar 2023 00:00:00 +0000 + + /events/2023-03-arctic/ + Dates: March 27-31, 2023 +Location: NCEAS Venue: Santa Barbara, CA +This 5-day in-person workshop will provide researchers with an introduction to advanced topics in computationally reproducible research in python, including software and techniques for working with very large datasets. This includes working in cloud computing environments, docker containers, and parallel processing using tools like parsl and dask. The workshop will also cover concrete methods for documenting and uploading data to the Arctic Data Center, advanced approaches to tracking data provenance, responsible research and data management practices including data sovereignty and the CARE principles, and ethical concerns with data-intensive modeling and analysis. + + + + Reproducible Practices for Arctic Research Using R + /events/2023-02-arctic/ + Mon, 27 Feb 2023 00:00:00 +0000 + + /events/2023-02-arctic/ + Dates: February 27 - March 3, 2023 +Location: Online +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara +This 5-day remote workshop will provided researchers with an overview of best data management practices, data science tools for cleaning and analyzing data, and concrete steps and methods for more easily documenting and preserving their data at the Arctic Data Center. Example tools included R, Rmarkdown, and git/GitHub. This course provided background in both the theory and practice of reproducible research, spanning all portions of the research lifecycle, from ethical data collection following the CARE principles to engage with local stakeholders, to data publishing. + + + + Fundamentals in Data Management for Qualitative and Quantitative Arctic Research + /events/2023-01-arctic/ + Mon, 30 Jan 2023 00:00:00 +0000 + + /events/2023-01-arctic/ + Dates: January 30 - February 3, 2023 +Location: NCEAS Venue: Santa Barbara, CA +This 5-day in-person workshop will provide researchers with an overview of reproducible and ethical research practices, steps and methods for more easily documenting and preserving their data at the Arctic Data Center, and an introduction to programming in R. Special attention will be paid to qualitative data management, including practices working with sensitive data. Example datasets will draw from natural and social sciences, and methods for conducting reproducible research will be discussed in the context of both qualitative and quantitative data. + + + + Scalable and Computationally Reproducible Approaches to Arctic Research + /events/2022-09-arctic/ + Sun, 18 Sep 2022 00:00:00 +0000 + + /events/2022-09-arctic/ + Dates: September 19 - 23, 2022 +Location: NCEAS Venue: Santa Barbara, CA +This 5-day in-person workshop will provide researchers with an introduction to advanced topics in computationally reproducible research in python, including software and techniques for working with very large datasets. This includes working in cloud computing environments, docker containers, and parallel processing using tools like parsl and dask. The workshop will also cover concrete methods for documenting and uploading data to the Arctic Data Center, advanced approaches to tracking data provenance, responsible research and data management practices including data sovereignty and the CARE principles, and ethical concerns with data-intensive modeling and analysis. + + + + Fundamentals in Data Management for Qualitative and Quantitative Arctic Research + /events/2022-04-arctic/ + Mon, 18 Apr 2022 00:00:00 +0000 + + /events/2022-04-arctic/ + Dates: April 18 - 22, 2022 +Location: NCEAS Venue: Santa Barbara, CA +This 5-day in-person workshop will provide researchers with an overview of reproducible and ethical research practices, steps and methods for more easily documenting and preserving their data at the Arctic Data Center, and an introduction to programming in R. Special attention will be paid to qualitative data management, including practices working with sensitive data. Example datasets will draw from natural and social sciences, and methods for conducting reproducible research will be discussed in the context of both qualitative and quantitative data. + + + + Arctic Data Center Training (February 2022) + /events/2022_02_arctic/ + Mon, 14 Feb 2022 00:00:00 +0000 + + /events/2022_02_arctic/ + Dates: February 14 - February 19, 2022 +Location: Online +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara The Arctic Data Center provides training in data science and data management, as these are critical skills for the stewardship of the data, software, and other research products that are preserved in the Arctic Data Center. A goal of the Arctic Data Center is to advance data archiving and promote reproducible science and data reuse. + + + + Open Science: Best Practices, Data Sovereignty and Co-production + /events/2022_03_arctic/ + Mon, 14 Feb 2022 00:00:00 +0000 + + /events/2022_03_arctic/ + Dates: March 29, 2022 +Location: Arctic Science Summit Week +Venue: Tromso, Norway +This workshop is a collaboration between the Arctic Data Center, ELOKA and the NNA Community Office, and will focus on the presentation of open science principles and best practices. Open science will be explored from the lens of reproducibility of research, Indigenous data sovereignty, and community data management. A combination of presentation and discussion will introduce participants to key topics, detail current recommended practices and highlight areas for future research. + + + + Reproducible Research Techniques for Synthesis (November 2021) + /events/2021_11_nceas/ + Fri, 05 Nov 2021 00:00:00 +0000 + + /events/2021_11_nceas/ + Dates: November 15-19, 2021 +Location: Remote +This 5-day workshop will provide researchers with an overview of best data management practices, data science tools, and concrete steps and methods for more easily producing transparent, reproducible workflows. This opportunity is for researchers from across career stages and sectors who want to gain fundamental data science skills that will improve their reproducible research techniques, particularly for the purposes of synthesis science. +Curriculum at a glance: Enable data reuse through better data management Metadata - what is it and how to write a quality data description Data modeling - tidy data for efficient access and storage Data publishing, citation, and credit Build reproducible scientific workflows Data munging with R tidyverse Working collaboratively - git and GitHub Writing functions in R Building packages for publishing reproducible research Communicate results effectively Literate analysis with RMarkdown Publishing analytical web pages with GitHub pages Data visualization with ggplot and leaflet For more detailed information on how to prepare for the workshop, see preparing for the workshop (below). + + + + Managing Ecological Data for Effective Use and Re-Use + /events/2021_08_esa/ + Wed, 28 Jul 2021 00:00:00 +0000 + + /events/2021_08_esa/ + Friday, August 6th, 2021 10:30 AM - 1:30 PM +Session Description While graduate students in ecology learn about methods for collecting and analyzing ecological data, there is less emphasis on managing and using the resulting data effectively. This is an increasingly important skill set as the research landscape changes. Researchers are increasingly engaging in collaboration across networks, many funding agencies require data management plans, journals are requiring that data and code be accessible, and society is increasingly expecting that research be reproducible. + + + + Open Science Synthesis for the Delta Science Program + /events/2021_09_delta/ + Thu, 27 May 2021 00:00:00 +0000 + + /events/2021_09_delta/ + In collaboration with the Delta Science Program we are running a 12 month facilitated research synthesis activity, supported by 3 one-week intensive training events. Curriculum material will focus on introducing Delta Researchers to best practices in, and application of, scientific computing and scientific software for reproducible science. In addition to developing and delivering learning curriculum, this collaboration will include the provision of data consulting, synthesis facilitation, and a remote workshop to conclude the group synthesis activities. + + + + Reproducible Research Techniques for Synthesis (July 2021) + /events/2021_07_nceas/ + Tue, 25 May 2021 00:00:00 +0000 + + /events/2021_07_nceas/ + Dates: July 8-9, 12-14, 2021 +Location: Remote +This 5-day workshop will provide researchers with an overview of best data management practices, data science tools, and concrete steps and methods for more easily producing transparent, reproducible workflows. This opportunity is for researchers from across career stages and sectors who want to gain fundamental data science skills that will improve their reproducible research techniques, particularly for the purposes of synthesis science. + + + + Reproducible Research Techniques for Synthesis (February 2021) + /events/2021_02_nceas/ + Fri, 05 Feb 2021 00:00:00 +0000 + + /events/2021_02_nceas/ + Dates: February 25-26, March 1-3, 2021 +Location: Remote +This 5-day workshop will provide researchers with an overview of best data management practices, data science tools, and concrete steps and methods for more easily producing transparent, reproducible workflows. This opportunity is for researchers from across career stages and sectors who want to gain fundamental data science skills that will improve their reproducible research techniques, particularly for the purposes of synthesis science. + + + + NEON Onboarding + /events/2020_12_neon/ + Tue, 01 Dec 2020 00:00:00 +0000 + + /events/2020_12_neon/ + Dates: December, 2020 Location: Virtual NEON Onboarding A self guided learning curricula to support new NEON postdocs as part of their onboarding experience. The curricula builds from the experience of ecological researchers, trainers, developers and information managers to provide resources and training in support of collaborative, reproducible research practices. +Materials Link to onboarding materials + + + + Reproducible Research Techniques for Synthesis (November 2020) + /events/2020_11_nceas/ + Thu, 12 Nov 2020 00:00:00 +0000 + + /events/2020_11_nceas/ + Dates: November 12 - November 18, 2020 +Location: Remote +This 5-day workshop will provide researchers with an overview of best data management practices, data science tools, and concrete steps and methods for more easily producing transparent, reproducible workflows. This opportunity is for researchers from across career stages and sectors who want to gain fundamental data science skills that will improve their reproducible research techniques, particularly for the purposes of synthesis science. + + + + Arctic Data Center Training (October 2020) + /events/2020_10_arctic/ + Mon, 19 Oct 2020 00:00:00 +0000 + + /events/2020_10_arctic/ + Dates: October 19 - October 23, 2020 +Location: Online +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara The Arctic Data Center provides training in data science and data management, as these are critical skills for the stewardship of the data, software, and other research products that are preserved in the Arctic Data Center. A goal of the Arctic Data Center is to advance data archiving and promote reproducible science and data reuse. + + + + Tools and practices for collaborative, reproducible data science + /events/2020_05_nceaswg/ + Fri, 08 May 2020 00:00:00 +0000 + + /events/2020_05_nceaswg/ + Dates: May 8, 2020 +Location: Remote This module is an introduction to the data science support NCEAS is providing to LTER and SNAPP working groups followed by a discussion on best practices about data management in a distributed team setup. Participants will have the opportunity to brainstorm on their data and computing needs. In the second part of the workshop, an introduction to the use of NCEAS analytical server and the concept of collaborative coding as a distributed team will be demonstrated to empower participants to develop their analytical workflows in a remote setup. + + + + Efficient virtual collaboration & facilitation for synthesis science + /events/2020_04_nceaswg/ + Fri, 24 Apr 2020 00:00:00 +0000 + + /events/2020_04_nceaswg/ + Dates: April 24, 2020 +Location: Remote This 3-hour module provides mentorship and facilitation training for Working Groups to develop skill sets, habits, and mindsets to make remote work and collaborative synthesis science more efficient and resilient. + + + + Openscapes Champions Workshop with NOAA + /events/2020_02_openscapes/ + Wed, 26 Feb 2020 00:00:00 +0000 + + /events/2020_02_openscapes/ + Dates: February 26 - February 27, 2020 +Location: Woods Hole, Massachusetts. NOAA Northeast Fisheries Science Center. Through in-person Workshops, cohorts of research groups participate over a 2 full days. Workshops are designed to be engaging, requiring active participation through discussion, live-notetaking in Google Docs, and breakout group activities. +Openscapes is operated by the National Center for Ecological Analysis & Synthesis (NCEAS) and is being incubated by a Mozilla Fellowship awarded to Julia Stewart Lowndes. + + + + Data Science and Collaboration Skills for Integrative Conservation Science + /events/2020_02_snapp/ + Tue, 18 Feb 2020 00:00:00 +0000 + + /events/2020_02_snapp/ + Dates: February 18 - February 21, 2020 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara +This intensive 4-day workshop on Data Science and Collaboration Skills for Integrative Conservation Science will be held at NCEAS, Santa Barbara, CA from Feb 18 to Feb 21, 2020. +This training, sponsored by SNAPP, aims to bring together the SNAPP and NCEAS postdoctoral associates to foster communities and collaboration, as well as promote scientific computing and open science best practices. + + + + Reproducible Research Techniques for Synthesis (February 2020) + /events/2020_02_nceas/ + Mon, 03 Feb 2020 00:00:00 +0000 + + /events/2020_02_nceas/ + Dates: February 3 - February 7, 2020 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara This 5-day workshop will provide researchers with an overview of best data management practices, data science tools, and concrete steps and methods for more easily producing transparent, reproducible workflows. This opportunity is for researchers from across career stages and sectors who want to gain fundamental data science skills that will improve their reproducible research techniques, particularly for the purposes of synthesis science. + + + + Reproducible Research Techniques for Synthesis (November 2019) + /events/2019_11_nceas/ + Mon, 04 Nov 2019 00:00:00 +0000 + + /events/2019_11_nceas/ + Dates: November 4 - November 8, 2019 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara This 5-day workshop will provide researchers with an overview of best data management practices, data science tools, and concrete steps and methods for more easily producing transparent, reproducible workflows. This opportunity is for researchers from across career stages and sectors who want to gain fundamental data science skills that will improve their reproducible research techniques, particularly for the purposes of synthesis science. + + + + Arctic Data Center Training (October 2019) + /events/2019_10_arctic/ + Mon, 07 Oct 2019 00:00:00 +0000 + + /events/2019_10_arctic/ + Dates: October 7 - October 11, 2019 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara The Arctic Data Center provides training in data science and data management, as these are critical skills for the stewardship of the data, software, and other research products that are preserved in the Arctic Data Center. A goal of the Arctic Data Center is to advance data archiving and promote reproducible science and data reuse. + + + + Arctic Data Center Training (February 2019) + /events/2019_02_arctic/ + Mon, 11 Feb 2019 00:00:00 +0000 + + /events/2019_02_arctic/ + Dates: February 11 - February 15, 2019 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara The Arctic Data Center provides training in data science and data management, as these are critical skills for the stewardship of the data, software, and other research products that are preserved in the Arctic Data Center. A goal of the Arctic Data Center is to advance data archiving and promote reproducible science and data reuse. + + + + Arctic Data Center Training (January 2019) + /events/2019_01_arctic/ + Mon, 14 Jan 2019 00:00:00 +0000 + + /events/2019_01_arctic/ + Dates: January 14 - January 18, 2019 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara The Arctic Data Center provides training in data science and data management, as these are critical skills for the stewardship of the data, software, and other research products that are preserved in the Arctic Data Center. A goal of the Arctic Data Center is to advance data archiving and promote reproducible science and data reuse. + + + + Openscapes Champions Cohort sponsored by Mozilla + /events/2019_01_openscapes/ + Thu, 10 Jan 2019 00:00:00 +0000 + + /events/2019_01_openscapes/ + Dates: January 10 - May 24, 2019 +Location: Remote In the Long-term Remote Program, Cohorts of research groups participate over a four-month period, with two Cohort Calls each month. Calls are designed to be engaging, requiring discussion and active participation through live-notetaking in Google Docs and video Zoom (group and breakouts). +Openscapes is operated by the National Center for Ecological Analysis & Synthesis (NCEAS) and is being incubated by a Mozilla Fellowship awarded to Julia Stewart Lowndes. + + + + Arctic Data Center Training (August 2018) + /events/2018_08_arctic/ + Mon, 13 Aug 2018 00:00:00 +0000 + + /events/2018_08_arctic/ + Dates: August 13 - August 17, 2018 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara The Arctic Data Center provides training in data science and data management, as these are critical skills for the stewardship of the data, software, and other research products that are preserved in the Arctic Data Center. A goal of the Arctic Data Center is to advance data archiving and promote reproducible science and data reuse. + + + + Dataset Publishing with the Arctic Data Center (June 2018) + /events/2018_06_arctic/ + Fri, 22 Jun 2018 00:00:00 +0000 + + /events/2018_06_arctic/ + Dates: June 22, 2018 12:30 to 14:00 +Location: Davos, Switzerland +Venue: POLAR 2018 Open Science Conference +This hands-on session will cover (1) Open data archives, especially the Arctic Data Center; (2) What science metadata is and how it can be used; (3) How data and code can be documented and published in open data archives; (4) Web-based submission, and (5) Submission using R (pending sufficient time). +Course overview The Arctic Data Center conducts training in data science and management, both of which are critical skills for stewardship of data, software, and other products of research that are preserved at the Arctic Data Center. + + + + Tools for Data Science in Arctic Research (July 2017) + /events/2017_07_arctic/ + Mon, 31 Jul 2017 00:00:00 +0000 + + /events/2017_07_arctic/ + Dates: July 31 - Aug 1, 2017 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara The Arctic Data Center provides training in data science and data management, as these are critical skills for the stewardship of the data, software, and other research products that are preserved in the Arctic Data Center. A goal of the Arctic Data Center is to advance data archiving and promote reproducible science and data reuse. + + + + Open Science for Synthesis: Gulf Research Program Workshop + /events/2017_07_oss/ + Mon, 10 Jul 2017 00:00:00 +0000 + + /events/2017_07_oss/ + Dates: July 10 - July 28, 2017 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara +The primary goal of the Open Science for Synthesis: Gulf Research Program Workshop is to provide hands-on experience with contemporary open science tools from command line to data to communication. Team science is promoted. Practice and real data are used in groups to apply skills we explore. +Week 1. + + + + \ No newline at end of file diff --git a/public/events/page/1/index.html b/public/events/page/1/index.html new file mode 100644 index 00000000..666ee42c --- /dev/null +++ b/public/events/page/1/index.html @@ -0,0 +1 @@ +/events/ \ No newline at end of file diff --git a/public/events/page/2/index.html b/public/events/page/2/index.html new file mode 100644 index 00000000..cbeb80ee --- /dev/null +++ b/public/events/page/2/index.html @@ -0,0 +1,403 @@ + + + + + + + NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+

+ Events +

+ +
+
+
+ + +
+ +
+
+
+ +
+
+

+ + Managing Ecological Data for Effective Use and Re-Use + +

+ +
+
+
+ +
+
+

+ + Open Science Synthesis for the Delta Science Program + +

+ +
+
+
+ +
+
+

+ + Reproducible Research Techniques for Synthesis (July 2021) + +

+ +
+
+
+ +
+
+

+ + Reproducible Research Techniques for Synthesis (February 2021) + +

+ +
+
+
+ +
+
+

+ + NEON Onboarding + +

+ +
+
+
+ +
+
+

+ + Reproducible Research Techniques for Synthesis (November 2020) + +

+ +
+
+
+ +
+
+

+ + Arctic Data Center Training (October 2020) + +

+ +
+
+
+ +
+
+

+ + Tools and practices for collaborative, reproducible data science + +

+ +
+
+
+ +
+
+

+ + Efficient virtual collaboration & facilitation for synthesis science + +

+ +
+
+
+ +
+
+

+ + Openscapes Champions Workshop with NOAA + +

+ +
+
+
+ +
+ + + +
+ +
+ + + + + + + + + diff --git a/public/events/page/3/index.html b/public/events/page/3/index.html new file mode 100644 index 00000000..d0c36c48 --- /dev/null +++ b/public/events/page/3/index.html @@ -0,0 +1,413 @@ + + + + + + + NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+

+ Events +

+ +
+
+
+ + +
+ +
+
+
+ +
+
+

+ + Data Science and Collaboration Skills for Integrative Conservation Science + +

+ +
+
+
+ +
+
+

+ + Reproducible Research Techniques for Synthesis (February 2020) + +

+ +
+
+
+ +
+
+

+ + Reproducible Research Techniques for Synthesis (November 2019) + +

+ +
+
+
+ +
+
+

+ + Arctic Data Center Training (October 2019) + +

+ +
+
+
+ +
+
+

+ + Arctic Data Center Training (February 2019) + +

+ +
+
+
+ +
+
+

+ + Arctic Data Center Training (January 2019) + +

+ +
+
+
+ +
+
+

+ + Openscapes Champions Cohort sponsored by Mozilla + +

+ +
+
+
+ +
+
+

+ + Arctic Data Center Training (August 2018) + +

+ +
+
+
+ +
+
+

+ + Dataset Publishing with the Arctic Data Center (June 2018) + +

+ +
+
+
+ +
+
+

+ + Tools for Data Science in Arctic Research (July 2017) + +

+ +
+
+
+ +
+ + + +
+ +
+ + + + + + + + + diff --git a/public/events/page/4/index.html b/public/events/page/4/index.html new file mode 100644 index 00000000..22d089f2 --- /dev/null +++ b/public/events/page/4/index.html @@ -0,0 +1,267 @@ + + + + + + + NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+

+ Events +

+ +
+
+
+ + +
+ +
+
+
+ +
+
+

+ + Open Science for Synthesis: Gulf Research Program Workshop + +

+ +
+
+
+ +
+ + + +
+ +
+ + + + + + + + + diff --git a/public/files/tempeco_DMP-2.pdf b/public/files/tempeco_DMP-2.pdf new file mode 100644 index 00000000..32032513 Binary files /dev/null and b/public/files/tempeco_DMP-2.pdf differ diff --git a/public/images/FAIR_CARE.png b/public/images/FAIR_CARE.png new file mode 100644 index 00000000..3f3a1132 Binary files /dev/null and b/public/images/FAIR_CARE.png differ diff --git a/public/images/FAIRsFAIR.png b/public/images/FAIRsFAIR.png new file mode 100644 index 00000000..562dde76 Binary files /dev/null and b/public/images/FAIRsFAIR.png differ diff --git a/public/images/Mountains.jpg b/public/images/Mountains.jpg new file mode 100644 index 00000000..1c261dc4 Binary files /dev/null and b/public/images/Mountains.jpg differ diff --git a/public/images/NCEAS_logo.png b/public/images/NCEAS_logo.png new file mode 100644 index 00000000..a60a88ce Binary files /dev/null and b/public/images/NCEAS_logo.png differ diff --git a/public/images/NSF_Logo.jpg b/public/images/NSF_Logo.jpg new file mode 100644 index 00000000..00d118e6 Binary files /dev/null and b/public/images/NSF_Logo.jpg differ diff --git a/public/images/alaska_population.png b/public/images/alaska_population.png new file mode 100644 index 00000000..16465fea Binary files /dev/null and b/public/images/alaska_population.png differ diff --git a/public/images/allison-horst-jenny-bryan-quote.png b/public/images/allison-horst-jenny-bryan-quote.png new file mode 100644 index 00000000..4c44b266 Binary files /dev/null and b/public/images/allison-horst-jenny-bryan-quote.png differ diff --git a/public/images/delta/delta-logo.png b/public/images/delta/delta-logo.png new file mode 100644 index 00000000..606dd02c Binary files /dev/null and b/public/images/delta/delta-logo.png differ diff --git a/public/images/ethical-dataset-retractions.png b/public/images/ethical-dataset-retractions.png new file mode 100644 index 00000000..4f9ea271 Binary files /dev/null and b/public/images/ethical-dataset-retractions.png differ diff --git a/public/images/fieldwork.jpg b/public/images/fieldwork.jpg new file mode 100644 index 00000000..366b5d21 Binary files /dev/null and b/public/images/fieldwork.jpg differ diff --git a/public/images/fishing.jpg b/public/images/fishing.jpg new file mode 100644 index 00000000..0c09b690 Binary files /dev/null and b/public/images/fishing.jpg differ diff --git a/public/images/force11-cope-logos.png b/public/images/force11-cope-logos.png new file mode 100644 index 00000000..f35d2a85 Binary files /dev/null and b/public/images/force11-cope-logos.png differ diff --git a/public/images/git-collab-repos.svg b/public/images/git-collab-repos.svg new file mode 100644 index 00000000..4db4c4c1 --- /dev/null +++ b/public/images/git-collab-repos.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/git-conflict-00-lines-changed.png b/public/images/git-conflict-00-lines-changed.png new file mode 100644 index 00000000..a289551a Binary files /dev/null and b/public/images/git-conflict-00-lines-changed.png differ diff --git a/public/images/git-conflict-01-push-error.png b/public/images/git-conflict-01-push-error.png new file mode 100644 index 00000000..7e1306c6 Binary files /dev/null and b/public/images/git-conflict-01-push-error.png differ diff --git a/public/images/git-conflict-02-pull-error.png b/public/images/git-conflict-02-pull-error.png new file mode 100644 index 00000000..609805b4 Binary files /dev/null and b/public/images/git-conflict-02-pull-error.png differ diff --git a/public/images/git-conflict-03-conflict.png b/public/images/git-conflict-03-conflict.png new file mode 100644 index 00000000..2d6d9045 Binary files /dev/null and b/public/images/git-conflict-03-conflict.png differ diff --git a/public/images/git-conflict-04-conflict-tags.png b/public/images/git-conflict-04-conflict-tags.png new file mode 100644 index 00000000..eb8d5cb0 Binary files /dev/null and b/public/images/git-conflict-04-conflict-tags.png differ diff --git a/public/images/git-conflict-05-resolved-file.png b/public/images/git-conflict-05-resolved-file.png new file mode 100644 index 00000000..b558f119 Binary files /dev/null and b/public/images/git-conflict-05-resolved-file.png differ diff --git a/public/images/git-conflict-06-commit-resolved.png b/public/images/git-conflict-06-commit-resolved.png new file mode 100644 index 00000000..669d8add Binary files /dev/null and b/public/images/git-conflict-06-commit-resolved.png differ diff --git a/public/images/git-conflict-07-push-resolved.png b/public/images/git-conflict-07-push-resolved.png new file mode 100644 index 00000000..66d7df6c Binary files /dev/null and b/public/images/git-conflict-07-push-resolved.png differ diff --git a/public/images/git-conflict-08-history.png b/public/images/git-conflict-08-history.png new file mode 100644 index 00000000..ba77318d Binary files /dev/null and b/public/images/git-conflict-08-history.png differ diff --git a/public/images/git-index-page.png b/public/images/git-index-page.png new file mode 100644 index 00000000..f549aded Binary files /dev/null and b/public/images/git-index-page.png differ diff --git a/public/images/git-xkcd-comic.png b/public/images/git-xkcd-comic.png new file mode 100644 index 00000000..3f35d2d7 Binary files /dev/null and b/public/images/git-xkcd-comic.png differ diff --git a/public/images/github-clone-url-owner.png b/public/images/github-clone-url-owner.png new file mode 100644 index 00000000..0f1e834e Binary files /dev/null and b/public/images/github-clone-url-owner.png differ diff --git a/public/images/github-collaborators.png b/public/images/github-collaborators.png new file mode 100644 index 00000000..e971f578 Binary files /dev/null and b/public/images/github-collaborators.png differ diff --git a/public/images/github_pages.png b/public/images/github_pages.png new file mode 100644 index 00000000..2be2e2be Binary files /dev/null and b/public/images/github_pages.png differ diff --git a/public/images/gohugo-default-sample-hero-image.jpg b/public/images/gohugo-default-sample-hero-image.jpg new file mode 100644 index 00000000..06815836 Binary files /dev/null and b/public/images/gohugo-default-sample-hero-image.jpg differ diff --git a/public/images/group-work.jpg b/public/images/group-work.jpg new file mode 100644 index 00000000..9875a3de Binary files /dev/null and b/public/images/group-work.jpg differ diff --git a/public/images/gsheets-access.png b/public/images/gsheets-access.png new file mode 100644 index 00000000..26c54af2 Binary files /dev/null and b/public/images/gsheets-access.png differ diff --git a/public/images/horst_openscapes.jpg b/public/images/horst_openscapes.jpg new file mode 100644 index 00000000..7877d3b4 Binary files /dev/null and b/public/images/horst_openscapes.jpg differ diff --git a/public/images/nceas.png b/public/images/nceas.png new file mode 100644 index 00000000..4a98b7ad Binary files /dev/null and b/public/images/nceas.png differ diff --git a/public/images/phdcomics_031305s_authorlist.gif b/public/images/phdcomics_031305s_authorlist.gif new file mode 100755 index 00000000..a9fd028e Binary files /dev/null and b/public/images/phdcomics_031305s_authorlist.gif differ diff --git a/public/images/projections-esri-blog.jpg b/public/images/projections-esri-blog.jpg new file mode 100644 index 00000000..12df9cdd Binary files /dev/null and b/public/images/projections-esri-blog.jpg differ diff --git a/public/images/rocky-mountains.jpg b/public/images/rocky-mountains.jpg new file mode 100644 index 00000000..5b831cf8 Binary files /dev/null and b/public/images/rocky-mountains.jpg differ diff --git a/public/images/rstudio-commit-push.png b/public/images/rstudio-commit-push.png new file mode 100644 index 00000000..62f66eff Binary files /dev/null and b/public/images/rstudio-commit-push.png differ diff --git a/public/images/rstudio-merge-conflict.png b/public/images/rstudio-merge-conflict.png new file mode 100644 index 00000000..83bbce17 Binary files /dev/null and b/public/images/rstudio-merge-conflict.png differ diff --git a/public/images/shiny-architecture.png b/public/images/shiny-architecture.png new file mode 100644 index 00000000..95abcdd3 Binary files /dev/null and b/public/images/shiny-architecture.png differ diff --git a/public/images/shiny-default-app.png b/public/images/shiny-default-app.png new file mode 100644 index 00000000..6b9b9dfe Binary files /dev/null and b/public/images/shiny-default-app.png differ diff --git a/public/images/shiny-io-account.png b/public/images/shiny-io-account.png new file mode 100644 index 00000000..5349f702 Binary files /dev/null and b/public/images/shiny-io-account.png differ diff --git a/public/images/shiny-layout-1.png b/public/images/shiny-layout-1.png new file mode 100644 index 00000000..0c3efb2f Binary files /dev/null and b/public/images/shiny-layout-1.png differ diff --git a/public/images/shiny-layout-2.png b/public/images/shiny-layout-2.png new file mode 100644 index 00000000..eedffe87 Binary files /dev/null and b/public/images/shiny-layout-2.png differ diff --git a/public/images/shiny-new-app.png b/public/images/shiny-new-app.png new file mode 100644 index 00000000..6917cc31 Binary files /dev/null and b/public/images/shiny-new-app.png differ diff --git a/public/images/shiny-publish.png b/public/images/shiny-publish.png new file mode 100644 index 00000000..ab09692f Binary files /dev/null and b/public/images/shiny-publish.png differ diff --git a/public/images/shiny-sasap-app.png b/public/images/shiny-sasap-app.png new file mode 100644 index 00000000..b639622e Binary files /dev/null and b/public/images/shiny-sasap-app.png differ diff --git a/public/images/shiny-yolo-1.png b/public/images/shiny-yolo-1.png new file mode 100644 index 00000000..e77832b9 Binary files /dev/null and b/public/images/shiny-yolo-1.png differ diff --git a/public/images/shiny-yolo-2.png b/public/images/shiny-yolo-2.png new file mode 100644 index 00000000..a409c6b0 Binary files /dev/null and b/public/images/shiny-yolo-2.png differ diff --git a/public/images/shiny-yolo-app.png b/public/images/shiny-yolo-app.png new file mode 100644 index 00000000..4b8fddf6 Binary files /dev/null and b/public/images/shiny-yolo-app.png differ diff --git a/public/images/short-course.jpg b/public/images/short-course.jpg new file mode 100644 index 00000000..33c01bef Binary files /dev/null and b/public/images/short-course.jpg differ diff --git a/public/images/sierra-nevada.jpg b/public/images/sierra-nevada.jpg new file mode 100644 index 00000000..a70dbd20 Binary files /dev/null and b/public/images/sierra-nevada.jpg differ diff --git a/public/images/survey_comparison.png b/public/images/survey_comparison.png new file mode 100644 index 00000000..f80360f4 Binary files /dev/null and b/public/images/survey_comparison.png differ diff --git a/public/images/survey_consent.png b/public/images/survey_consent.png new file mode 100644 index 00000000..317a26c4 Binary files /dev/null and b/public/images/survey_consent.png differ diff --git a/public/images/survey_main.png b/public/images/survey_main.png new file mode 100644 index 00000000..0f2a2ef6 Binary files /dev/null and b/public/images/survey_main.png differ diff --git a/public/index.html b/public/index.html new file mode 100644 index 00000000..60195906 --- /dev/null +++ b/public/index.html @@ -0,0 +1,580 @@ + + + + + + + + + +NCEAS Open Science Synthesis for the Delta Science Program + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+ + +
+ + + +
+ +
+
+

NCEAS Open Science Synthesis for the Delta Science Program

+
+ + + +
+ + + + +
+ + +
+ +
+

Overview

+ +
+
+
+

+
+
+
+
+

+
+
+
+

About this training

+

NCEAS Open Science Synthesis training consists of three 1-week long workshops, geared towards early career researchers. Participants engage in a mix of lectures, exercises, and synthesis research groups to undertake synthesis while learning and implementing best practices for open data science.

+ +
+
+

Why NCEAS

+

The National Center for Ecological Analysis and Synthesis (NCEAS), a research affiliate of UCSB, is a leading expert on interdisciplinary data science and works collaboratively to answer the world’s largest and most complex questions. The NCEAS approach leverages existing data and employs a team science philosophy to squeeze out all potential insights and solutions efficiently - this is called synthesis science.

+

NCEAS has over 25 years of success with this model among working groups and environmental professionals. Together with the Delta Science Program and the Delta Stewardship Council we are excited to pass along skills, workflows, mindsets learn throughout the years.

+
+

Week 2: Open Tools for Analysis and Visualization

+

Aug 28 - Sep 1, 2023

+
    +
  • Strengthen core knowledge of version control and workflow
  • +
  • Introduce metaanalysis concepts and tools
  • +
  • Approaches for geospatial visualization
  • +
  • Data tools for qualitative data
  • +
+
+
+
+

Schedule

+

UPDATE IMAGE WITH WEEK 2 SCHEDULE

+
+ +
+
+
+

Next training

+
+

Week 3: Scaling up and presenting synthesis

+

October 23 – 27, 2023

+
    +
  • Handling missing data
  • +
  • Big data workflows and parallel computing
  • +
  • Building scientific websites with R and Shiny
  • +
  • Synthesis presentations and next steps
  • +
+
+
+
+

Code of Conduct

+

By participating in this activity you agree to abide by the NCEAS Code of Conduct.

+
+
+

About this book

+

These written materials are the result of a continuous and collaborative effort at NCEAS with the support of DataONE, to help researchers make their work more transparent and reproducible. This work began in the early 2000’s, and reflects the expertise and diligence of many, many individuals. The primary authors for this version are listed in the citation below, with additional contributors recognized for their role in developing previous iterations of these or similar materials.

+

This work is licensed under a Creative Commons Attribution 4.0 International License.

+

Citation: Halina Do-Linh, Carmen Galaz García, Matthew B. Jones, Camila Vargas Poulsen. 2023. Open Science Synthesis training Week 2. NCEAS Learning Hub & Delta Stewardship Council.

+

Additional contributors: Ben Bolker, Julien Brun, Amber E. Budden, Jeanette Clark, Samantha Csik, Stephanie Hampton, Natasha Haycock-Chavez, Samanta Katz, Julie Lowndes, Erin McLean, Bryce Mecum, Deanna Pennington, Karthik Ram, Jim Regetz, Tracy Teal, Daphne Virlar-Knight, Leah Wasser.

+

This is a Quarto book. To learn more about Quarto books visit https://quarto.org/docs/books.

+ + +
+
+ +
+ + +
+ + + + \ No newline at end of file diff --git a/public/index.xml b/public/index.xml new file mode 100644 index 00000000..05e2b44f --- /dev/null +++ b/public/index.xml @@ -0,0 +1,360 @@ + + + + NCEAS Training Materials Catalog + / + Recent content on NCEAS Training Materials Catalog + Hugo -- gohugo.io + en-us + Mon, 26 Jun 2023 00:00:00 +0000 + + + + + + Open Science Synthesis for the Delta Science Program + /events/2023-06-delta/ + Mon, 26 Jun 2023 00:00:00 +0000 + + /events/2023-06-delta/ + In collaboration with the Delta Science Program we are running a 12 month facilitated research synthesis activity, supported by 3 one-week intensive training events. Curriculum material will focus on introducing Delta Researchers to best practices in, and application of, scientific computing and scientific software for reproducible science. In addition to developing and delivering learning curriculum, this collaboration will include the provision of data consulting, synthesis facilitation, and a remote workshop to conclude the group synthesis activities. + + + + NCEAS Learning Hub coreR Course + /events/2023-04-corer/ + Mon, 03 Apr 2023 00:00:00 +0000 + + /events/2023-04-corer/ + Previously called the Reproducible Research Techniques for Synthesis course +Dates: April 3-7, 2023 +Location: NCEAS Venue: Santa Barbara, CA +A five-day immersion in R programming for environmental data science. Researchers will gain experience with essential data science tools and best practices to increase their capacity as collaborators, reproducible coders, and open scientists. This course is taught both in-person and virtually. +Materials Link to course book +Instructors Name Email Halina Do-Linh dolinh@nceas. + + + + Scalable and Computationally Reproducible Approaches to Arctic Research + /events/2023-03-arctic/ + Thu, 23 Mar 2023 00:00:00 +0000 + + /events/2023-03-arctic/ + Dates: March 27-31, 2023 +Location: NCEAS Venue: Santa Barbara, CA +This 5-day in-person workshop will provide researchers with an introduction to advanced topics in computationally reproducible research in python, including software and techniques for working with very large datasets. This includes working in cloud computing environments, docker containers, and parallel processing using tools like parsl and dask. The workshop will also cover concrete methods for documenting and uploading data to the Arctic Data Center, advanced approaches to tracking data provenance, responsible research and data management practices including data sovereignty and the CARE principles, and ethical concerns with data-intensive modeling and analysis. + + + + Reproducible Practices for Arctic Research Using R + /events/2023-02-arctic/ + Mon, 27 Feb 2023 00:00:00 +0000 + + /events/2023-02-arctic/ + Dates: February 27 - March 3, 2023 +Location: Online +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara +This 5-day remote workshop will provided researchers with an overview of best data management practices, data science tools for cleaning and analyzing data, and concrete steps and methods for more easily documenting and preserving their data at the Arctic Data Center. Example tools included R, Rmarkdown, and git/GitHub. This course provided background in both the theory and practice of reproducible research, spanning all portions of the research lifecycle, from ethical data collection following the CARE principles to engage with local stakeholders, to data publishing. + + + + Fundamentals in Data Management for Qualitative and Quantitative Arctic Research + /events/2023-01-arctic/ + Mon, 30 Jan 2023 00:00:00 +0000 + + /events/2023-01-arctic/ + Dates: January 30 - February 3, 2023 +Location: NCEAS Venue: Santa Barbara, CA +This 5-day in-person workshop will provide researchers with an overview of reproducible and ethical research practices, steps and methods for more easily documenting and preserving their data at the Arctic Data Center, and an introduction to programming in R. Special attention will be paid to qualitative data management, including practices working with sensitive data. Example datasets will draw from natural and social sciences, and methods for conducting reproducible research will be discussed in the context of both qualitative and quantitative data. + + + + Scalable and Computationally Reproducible Approaches to Arctic Research + /events/2022-09-arctic/ + Sun, 18 Sep 2022 00:00:00 +0000 + + /events/2022-09-arctic/ + Dates: September 19 - 23, 2022 +Location: NCEAS Venue: Santa Barbara, CA +This 5-day in-person workshop will provide researchers with an introduction to advanced topics in computationally reproducible research in python, including software and techniques for working with very large datasets. This includes working in cloud computing environments, docker containers, and parallel processing using tools like parsl and dask. The workshop will also cover concrete methods for documenting and uploading data to the Arctic Data Center, advanced approaches to tracking data provenance, responsible research and data management practices including data sovereignty and the CARE principles, and ethical concerns with data-intensive modeling and analysis. + + + + Fundamentals in Data Management for Qualitative and Quantitative Arctic Research + /events/2022-04-arctic/ + Mon, 18 Apr 2022 00:00:00 +0000 + + /events/2022-04-arctic/ + Dates: April 18 - 22, 2022 +Location: NCEAS Venue: Santa Barbara, CA +This 5-day in-person workshop will provide researchers with an overview of reproducible and ethical research practices, steps and methods for more easily documenting and preserving their data at the Arctic Data Center, and an introduction to programming in R. Special attention will be paid to qualitative data management, including practices working with sensitive data. Example datasets will draw from natural and social sciences, and methods for conducting reproducible research will be discussed in the context of both qualitative and quantitative data. + + + + Arctic Data Center Training (February 2022) + /events/2022_02_arctic/ + Mon, 14 Feb 2022 00:00:00 +0000 + + /events/2022_02_arctic/ + Dates: February 14 - February 19, 2022 +Location: Online +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara The Arctic Data Center provides training in data science and data management, as these are critical skills for the stewardship of the data, software, and other research products that are preserved in the Arctic Data Center. A goal of the Arctic Data Center is to advance data archiving and promote reproducible science and data reuse. + + + + Open Science: Best Practices, Data Sovereignty and Co-production + /events/2022_03_arctic/ + Mon, 14 Feb 2022 00:00:00 +0000 + + /events/2022_03_arctic/ + Dates: March 29, 2022 +Location: Arctic Science Summit Week +Venue: Tromso, Norway +This workshop is a collaboration between the Arctic Data Center, ELOKA and the NNA Community Office, and will focus on the presentation of open science principles and best practices. Open science will be explored from the lens of reproducibility of research, Indigenous data sovereignty, and community data management. A combination of presentation and discussion will introduce participants to key topics, detail current recommended practices and highlight areas for future research. + + + + Reproducible Research Techniques for Synthesis (November 2021) + /events/2021_11_nceas/ + Fri, 05 Nov 2021 00:00:00 +0000 + + /events/2021_11_nceas/ + Dates: November 15-19, 2021 +Location: Remote +This 5-day workshop will provide researchers with an overview of best data management practices, data science tools, and concrete steps and methods for more easily producing transparent, reproducible workflows. This opportunity is for researchers from across career stages and sectors who want to gain fundamental data science skills that will improve their reproducible research techniques, particularly for the purposes of synthesis science. +Curriculum at a glance: Enable data reuse through better data management Metadata - what is it and how to write a quality data description Data modeling - tidy data for efficient access and storage Data publishing, citation, and credit Build reproducible scientific workflows Data munging with R tidyverse Working collaboratively - git and GitHub Writing functions in R Building packages for publishing reproducible research Communicate results effectively Literate analysis with RMarkdown Publishing analytical web pages with GitHub pages Data visualization with ggplot and leaflet For more detailed information on how to prepare for the workshop, see preparing for the workshop (below). + + + + Managing Ecological Data for Effective Use and Re-Use + /events/2021_08_esa/ + Wed, 28 Jul 2021 00:00:00 +0000 + + /events/2021_08_esa/ + Friday, August 6th, 2021 10:30 AM - 1:30 PM +Session Description While graduate students in ecology learn about methods for collecting and analyzing ecological data, there is less emphasis on managing and using the resulting data effectively. This is an increasingly important skill set as the research landscape changes. Researchers are increasingly engaging in collaboration across networks, many funding agencies require data management plans, journals are requiring that data and code be accessible, and society is increasingly expecting that research be reproducible. + + + + Open Science Synthesis for the Delta Science Program + /events/2021_09_delta/ + Thu, 27 May 2021 00:00:00 +0000 + + /events/2021_09_delta/ + In collaboration with the Delta Science Program we are running a 12 month facilitated research synthesis activity, supported by 3 one-week intensive training events. Curriculum material will focus on introducing Delta Researchers to best practices in, and application of, scientific computing and scientific software for reproducible science. In addition to developing and delivering learning curriculum, this collaboration will include the provision of data consulting, synthesis facilitation, and a remote workshop to conclude the group synthesis activities. + + + + Reproducible Research Techniques for Synthesis (July 2021) + /events/2021_07_nceas/ + Tue, 25 May 2021 00:00:00 +0000 + + /events/2021_07_nceas/ + Dates: July 8-9, 12-14, 2021 +Location: Remote +This 5-day workshop will provide researchers with an overview of best data management practices, data science tools, and concrete steps and methods for more easily producing transparent, reproducible workflows. This opportunity is for researchers from across career stages and sectors who want to gain fundamental data science skills that will improve their reproducible research techniques, particularly for the purposes of synthesis science. + + + + Reproducible Research Techniques for Synthesis (February 2021) + /events/2021_02_nceas/ + Fri, 05 Feb 2021 00:00:00 +0000 + + /events/2021_02_nceas/ + Dates: February 25-26, March 1-3, 2021 +Location: Remote +This 5-day workshop will provide researchers with an overview of best data management practices, data science tools, and concrete steps and methods for more easily producing transparent, reproducible workflows. This opportunity is for researchers from across career stages and sectors who want to gain fundamental data science skills that will improve their reproducible research techniques, particularly for the purposes of synthesis science. + + + + NEON Onboarding + /events/2020_12_neon/ + Tue, 01 Dec 2020 00:00:00 +0000 + + /events/2020_12_neon/ + Dates: December, 2020 Location: Virtual NEON Onboarding A self guided learning curricula to support new NEON postdocs as part of their onboarding experience. The curricula builds from the experience of ecological researchers, trainers, developers and information managers to provide resources and training in support of collaborative, reproducible research practices. +Materials Link to onboarding materials + + + + Reproducible Research Techniques for Synthesis (November 2020) + /events/2020_11_nceas/ + Thu, 12 Nov 2020 00:00:00 +0000 + + /events/2020_11_nceas/ + Dates: November 12 - November 18, 2020 +Location: Remote +This 5-day workshop will provide researchers with an overview of best data management practices, data science tools, and concrete steps and methods for more easily producing transparent, reproducible workflows. This opportunity is for researchers from across career stages and sectors who want to gain fundamental data science skills that will improve their reproducible research techniques, particularly for the purposes of synthesis science. + + + + Arctic Data Center Training (October 2020) + /events/2020_10_arctic/ + Mon, 19 Oct 2020 00:00:00 +0000 + + /events/2020_10_arctic/ + Dates: October 19 - October 23, 2020 +Location: Online +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara The Arctic Data Center provides training in data science and data management, as these are critical skills for the stewardship of the data, software, and other research products that are preserved in the Arctic Data Center. A goal of the Arctic Data Center is to advance data archiving and promote reproducible science and data reuse. + + + + Tools and practices for collaborative, reproducible data science + /events/2020_05_nceaswg/ + Fri, 08 May 2020 00:00:00 +0000 + + /events/2020_05_nceaswg/ + Dates: May 8, 2020 +Location: Remote This module is an introduction to the data science support NCEAS is providing to LTER and SNAPP working groups followed by a discussion on best practices about data management in a distributed team setup. Participants will have the opportunity to brainstorm on their data and computing needs. In the second part of the workshop, an introduction to the use of NCEAS analytical server and the concept of collaborative coding as a distributed team will be demonstrated to empower participants to develop their analytical workflows in a remote setup. + + + + Efficient virtual collaboration & facilitation for synthesis science + /events/2020_04_nceaswg/ + Fri, 24 Apr 2020 00:00:00 +0000 + + /events/2020_04_nceaswg/ + Dates: April 24, 2020 +Location: Remote This 3-hour module provides mentorship and facilitation training for Working Groups to develop skill sets, habits, and mindsets to make remote work and collaborative synthesis science more efficient and resilient. + + + + Openscapes Champions Workshop with NOAA + /events/2020_02_openscapes/ + Wed, 26 Feb 2020 00:00:00 +0000 + + /events/2020_02_openscapes/ + Dates: February 26 - February 27, 2020 +Location: Woods Hole, Massachusetts. NOAA Northeast Fisheries Science Center. Through in-person Workshops, cohorts of research groups participate over a 2 full days. Workshops are designed to be engaging, requiring active participation through discussion, live-notetaking in Google Docs, and breakout group activities. +Openscapes is operated by the National Center for Ecological Analysis &amp; Synthesis (NCEAS) and is being incubated by a Mozilla Fellowship awarded to Julia Stewart Lowndes. + + + + Data Science and Collaboration Skills for Integrative Conservation Science + /events/2020_02_snapp/ + Tue, 18 Feb 2020 00:00:00 +0000 + + /events/2020_02_snapp/ + Dates: February 18 - February 21, 2020 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara +This intensive 4-day workshop on Data Science and Collaboration Skills for Integrative Conservation Science will be held at NCEAS, Santa Barbara, CA from Feb 18 to Feb 21, 2020. +This training, sponsored by SNAPP, aims to bring together the SNAPP and NCEAS postdoctoral associates to foster communities and collaboration, as well as promote scientific computing and open science best practices. + + + + Reproducible Research Techniques for Synthesis (February 2020) + /events/2020_02_nceas/ + Mon, 03 Feb 2020 00:00:00 +0000 + + /events/2020_02_nceas/ + Dates: February 3 - February 7, 2020 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara This 5-day workshop will provide researchers with an overview of best data management practices, data science tools, and concrete steps and methods for more easily producing transparent, reproducible workflows. This opportunity is for researchers from across career stages and sectors who want to gain fundamental data science skills that will improve their reproducible research techniques, particularly for the purposes of synthesis science. + + + + Reproducible Research Techniques for Synthesis (November 2019) + /events/2019_11_nceas/ + Mon, 04 Nov 2019 00:00:00 +0000 + + /events/2019_11_nceas/ + Dates: November 4 - November 8, 2019 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara This 5-day workshop will provide researchers with an overview of best data management practices, data science tools, and concrete steps and methods for more easily producing transparent, reproducible workflows. This opportunity is for researchers from across career stages and sectors who want to gain fundamental data science skills that will improve their reproducible research techniques, particularly for the purposes of synthesis science. + + + + Arctic Data Center Training (October 2019) + /events/2019_10_arctic/ + Mon, 07 Oct 2019 00:00:00 +0000 + + /events/2019_10_arctic/ + Dates: October 7 - October 11, 2019 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara The Arctic Data Center provides training in data science and data management, as these are critical skills for the stewardship of the data, software, and other research products that are preserved in the Arctic Data Center. A goal of the Arctic Data Center is to advance data archiving and promote reproducible science and data reuse. + + + + Arctic Data Center Training (February 2019) + /events/2019_02_arctic/ + Mon, 11 Feb 2019 00:00:00 +0000 + + /events/2019_02_arctic/ + Dates: February 11 - February 15, 2019 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara The Arctic Data Center provides training in data science and data management, as these are critical skills for the stewardship of the data, software, and other research products that are preserved in the Arctic Data Center. A goal of the Arctic Data Center is to advance data archiving and promote reproducible science and data reuse. + + + + Arctic Data Center Training (January 2019) + /events/2019_01_arctic/ + Mon, 14 Jan 2019 00:00:00 +0000 + + /events/2019_01_arctic/ + Dates: January 14 - January 18, 2019 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara The Arctic Data Center provides training in data science and data management, as these are critical skills for the stewardship of the data, software, and other research products that are preserved in the Arctic Data Center. A goal of the Arctic Data Center is to advance data archiving and promote reproducible science and data reuse. + + + + Openscapes Champions Cohort sponsored by Mozilla + /events/2019_01_openscapes/ + Thu, 10 Jan 2019 00:00:00 +0000 + + /events/2019_01_openscapes/ + Dates: January 10 - May 24, 2019 +Location: Remote In the Long-term Remote Program, Cohorts of research groups participate over a four-month period, with two Cohort Calls each month. Calls are designed to be engaging, requiring discussion and active participation through live-notetaking in Google Docs and video Zoom (group and breakouts). +Openscapes is operated by the National Center for Ecological Analysis &amp; Synthesis (NCEAS) and is being incubated by a Mozilla Fellowship awarded to Julia Stewart Lowndes. + + + + Arctic Data Center Training (August 2018) + /events/2018_08_arctic/ + Mon, 13 Aug 2018 00:00:00 +0000 + + /events/2018_08_arctic/ + Dates: August 13 - August 17, 2018 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara The Arctic Data Center provides training in data science and data management, as these are critical skills for the stewardship of the data, software, and other research products that are preserved in the Arctic Data Center. A goal of the Arctic Data Center is to advance data archiving and promote reproducible science and data reuse. + + + + Dataset Publishing with the Arctic Data Center (June 2018) + /events/2018_06_arctic/ + Fri, 22 Jun 2018 00:00:00 +0000 + + /events/2018_06_arctic/ + Dates: June 22, 2018 12:30 to 14:00 +Location: Davos, Switzerland +Venue: POLAR 2018 Open Science Conference +This hands-on session will cover (1) Open data archives, especially the Arctic Data Center; (2) What science metadata is and how it can be used; (3) How data and code can be documented and published in open data archives; (4) Web-based submission, and (5) Submission using R (pending sufficient time). +Course overview The Arctic Data Center conducts training in data science and management, both of which are critical skills for stewardship of data, software, and other products of research that are preserved at the Arctic Data Center. + + + + Tools for Data Science in Arctic Research (July 2017) + /events/2017_07_arctic/ + Mon, 31 Jul 2017 00:00:00 +0000 + + /events/2017_07_arctic/ + Dates: July 31 - Aug 1, 2017 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara The Arctic Data Center provides training in data science and data management, as these are critical skills for the stewardship of the data, software, and other research products that are preserved in the Arctic Data Center. A goal of the Arctic Data Center is to advance data archiving and promote reproducible science and data reuse. + + + + Open Science for Synthesis: Gulf Research Program Workshop + /events/2017_07_oss/ + Mon, 10 Jul 2017 00:00:00 +0000 + + /events/2017_07_oss/ + Dates: July 10 - July 28, 2017 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara +The primary goal of the Open Science for Synthesis: Gulf Research Program Workshop is to provide hands-on experience with contemporary open science tools from command line to data to communication. Team science is promoted. Practice and real data are used in groups to apply skills we explore. +Week 1. + + + + \ No newline at end of file diff --git a/public/post/2015-07-23-r-rmarkdown_files/figure-html/pie-1.png b/public/post/2015-07-23-r-rmarkdown_files/figure-html/pie-1.png new file mode 100644 index 00000000..0edf78b1 Binary files /dev/null and b/public/post/2015-07-23-r-rmarkdown_files/figure-html/pie-1.png differ diff --git a/public/search.json b/public/search.json new file mode 100644 index 00000000..0962b123 --- /dev/null +++ b/public/search.json @@ -0,0 +1,415 @@ +[ + { + "objectID": "index.html", + "href": "index.html", + "title": "NCEAS Open Science Synthesis for the Delta Science Program", + "section": "", + "text": "Overview" + }, + { + "objectID": "index.html#about-this-training", + "href": "index.html#about-this-training", + "title": "NCEAS Open Science Synthesis for the Delta Science Program", + "section": "About this training", + "text": "About this training\nNCEAS Open Science Synthesis training consists of three 1-week long workshops, geared towards early career researchers. Participants engage in a mix of lectures, exercises, and synthesis research groups to undertake synthesis while learning and implementing best practices for open data science." + }, + { + "objectID": "index.html#why-nceas", + "href": "index.html#why-nceas", + "title": "NCEAS Open Science Synthesis for the Delta Science Program", + "section": "Why NCEAS", + "text": "Why NCEAS\nThe National Center for Ecological Analysis and Synthesis (NCEAS), a research affiliate of UCSB, is a leading expert on interdisciplinary data science and works collaboratively to answer the world’s largest and most complex questions. The NCEAS approach leverages existing data and employs a team science philosophy to squeeze out all potential insights and solutions efficiently - this is called synthesis science.\nNCEAS has over 25 years of success with this model among working groups and environmental professionals. Together with the Delta Science Program and the Delta Stewardship Council we are excited to pass along skills, workflows, mindsets learn throughout the years.\n\nWeek 2: Open Tools for Analysis and Visualization\nAug 28 - Sep 1, 2023\n\nStrengthen core knowledge of version control and workflow\nIntroduce metaanalysis concepts and tools\nApproaches for geospatial visualization\nData tools for qualitative data" + }, + { + "objectID": "index.html#schedule", + "href": "index.html#schedule", + "title": "NCEAS Open Science Synthesis for the Delta Science Program", + "section": "Schedule", + "text": "Schedule\nUPDATE IMAGE WITH WEEK 2 SCHEDULE" + }, + { + "objectID": "index.html#next-training", + "href": "index.html#next-training", + "title": "NCEAS Open Science Synthesis for the Delta Science Program", + "section": "Next training", + "text": "Next training\n\nWeek 3: Scaling up and presenting synthesis\nOctober 23 – 27, 2023\n\nHandling missing data\nBig data workflows and parallel computing\nBuilding scientific websites with R and Shiny\nSynthesis presentations and next steps" + }, + { + "objectID": "index.html#code-of-conduct", + "href": "index.html#code-of-conduct", + "title": "NCEAS Open Science Synthesis for the Delta Science Program", + "section": "Code of Conduct", + "text": "Code of Conduct\nBy participating in this activity you agree to abide by the NCEAS Code of Conduct." + }, + { + "objectID": "index.html#about-this-book", + "href": "index.html#about-this-book", + "title": "NCEAS Open Science Synthesis for the Delta Science Program", + "section": "About this book", + "text": "About this book\nThese written materials are the result of a continuous and collaborative effort at NCEAS with the support of DataONE, to help researchers make their work more transparent and reproducible. This work began in the early 2000’s, and reflects the expertise and diligence of many, many individuals. The primary authors for this version are listed in the citation below, with additional contributors recognized for their role in developing previous iterations of these or similar materials.\nThis work is licensed under a Creative Commons Attribution 4.0 International License.\nCitation: Halina Do-Linh, Carmen Galaz García, Matthew B. Jones, Camila Vargas Poulsen. 2023. Open Science Synthesis training Week 2. NCEAS Learning Hub & Delta Stewardship Council.\nAdditional contributors: Ben Bolker, Julien Brun, Amber E. Budden, Jeanette Clark, Samantha Csik, Stephanie Hampton, Natasha Haycock-Chavez, Samanta Katz, Julie Lowndes, Erin McLean, Bryce Mecum, Deanna Pennington, Karthik Ram, Jim Regetz, Tracy Teal, Daphne Virlar-Knight, Leah Wasser.\nThis is a Quarto book. To learn more about Quarto books visit https://quarto.org/docs/books." + }, + { + "objectID": "session_01.html#learning-objectives", + "href": "session_01.html#learning-objectives", + "title": "1  Collaborating using Git and GitHub & Merge Conflicts", + "section": "Learning Objectives", + "text": "Learning Objectives\n\nApply the principles, features, and collaboration tools of Git and GitHub to effectively collaborate with colleagues on code\nAnalyze and evaluate common causes of conflicts that arise when collaborating on repositories\nDemonstrate the ability to resolve conflicts using Git conflict resolution techniques\nApply workflows and best practices that minimize conflicts on collaborative repositories" + }, + { + "objectID": "session_01.html#introduction-to-git-and-github-tools-for-collaboration", + "href": "session_01.html#introduction-to-git-and-github-tools-for-collaboration", + "title": "1  Collaborating using Git and GitHub & Merge Conflicts", + "section": "1.1 Introduction to Git and GitHub Tools for Collaboration", + "text": "1.1 Introduction to Git and GitHub Tools for Collaboration\n\n\n\nArtwork by Allison Horst\n\n\nGit is not only a powerful tool for individual work but also an excellent choice for collaborating with friends and colleagues. Git ensures that after you’ve completed your contributions to a repository, you can confidently synchronize your changes with changes made by others.\nOne of the easiest and most effective ways to collaborate using Git is by utilizing a shared repository on a hosting service like GitHub. This shared repository acts as a central hub, enabling collaborators to effortlessly exchange and merge their changes. With Git and a shared repository, you can collaborate seamlessly and work confidently, knowing that your changes will be integrated smoothly with those of your collaborators.\n\n\n\nGraphic from Atlassian\n\n\nThere are many advanced techniques for synchronizing Git repositories, but let’s start with a simple example.\nIn this example, the Collaborator will clone a copy of the Owner’s repository from GitHub, and the Owner will grant them Collaborator status, enabling the Collaborator to directly pull and push from the Owner’s GitHub repository." + }, + { + "objectID": "session_01.html#collaborating-with-a-trusted-colleague-without-conflicts", + "href": "session_01.html#collaborating-with-a-trusted-colleague-without-conflicts", + "title": "1  Collaborating using Git and GitHub & Merge Conflicts", + "section": "1.2 Collaborating with a trusted colleague without conflicts", + "text": "1.2 Collaborating with a trusted colleague without conflicts\nWe start our collaboration by giving a trusted colleague access to our repository on GitHub. In this example, we define the Owner as the individual who owns the repository, and the Collaborator as the person whom the Owner chooses to give permission to make changes to their repository.\nThe Collaborator will make changes to the repository and then push those changes to the shared repository on GitHub. The Owner will then use pull to retrieve the changes without encountering any conflicts. This is the most ideal workflow.\nThe instructors will demonstrate this process in the next section.\n\nStep 0: Owner adds Collaborator to shared repository\nThe Owner must change the settings of the repository and give the Collaborator access to the repository by inviting them as a collaborator to the repository. Once the Collaborator has accepted the invite, they can contribute to the repository.\n\n\n\n\n\n\n\nStep 1: Collaborator clone\nTo be able to contribute to a repository, the Collaborator must clone the repository from the Owner’s GitHub account. To do this, the Collaborator should visit the GitHub page for the Owner’s repository, and then copy the clone URL. In R Studio, the Collaborator will create a new project from version control by pasting this clone URL into the appropriate dialog (see the earlier chapter introducing GitHub).\n\n\n\nStep 2: Collaborator edit\nWith a clone copied locally, the Collaborator can now make changes to the README.md file in the repository, adding a line or statement somewhere noticeable near the top. Save your changes.\n\n\nStep 3: Collaborator commit and push\nTo sync changes, the Collaborator will need to add, commit, and push their changes to the Owner’s repository. But before doing so, it’s good practice to pull immediately before committing to ensure you have the most recent changes from the Owner. So, in RStudio’s Git tab, first click the “Diff” button to open the Git window, and then press the green “Pull” down arrow button. This will fetch any recent changes from the origin repository and merge them. Next, add the changed README.Rmd file to be committed by clicking the check box next to it, type in a commit message, and click “Commit”. Once that finishes, then the Collaborator can immediately click “Push” to send the commits to the Owner’s GitHub repository.\n\n\n\n\n\n\n\nStep 4: Owner pull\nNow, the Owner can open their local working copy of the code in RStudio, and pull those changes down to their local copy.\nCongrats, the Owner now has your changes!\n\n\nStep 5: Owner edits, commit, and push\nNext, the Owner should do the same. Make changes to a file in the repository, save it, pull to make sure no new changes have been made while editing, and then add, commit, and push the Owner changes to GitHub.\n\n\nStep 6: Collaborator pull\nThe Collaborator can now pull down those Owner changes, and all copies are once again fully synced. And you’re off to collaborating." + }, + { + "objectID": "session_01.html#ex1-no-conflict", + "href": "session_01.html#ex1-no-conflict", + "title": "1  Collaborating using Git and GitHub & Merge Conflicts", + "section": "1.3 Exercise 1: With a partner collaborate in a repository without a merge conflict", + "text": "1.3 Exercise 1: With a partner collaborate in a repository without a merge conflict\n\n\n\n\n\n\nSetup\n\n\n\n\nGet into pairs, then choose one person as the Owner and one as the Collaborator\nBoth logon to GitHub\n\nThese next steps are for the Owner:\n\nNavigate to the {FIRSTNAME}_test repository\nGo to “Settings” and navigate to “Collaborators” in the “Access” section on the left-hand side\nUnder “Manage Access” click the button “Add people” and type the username of your Collaborator in the search box\nOnce you’ve found the correct username, click “Add {Collaborator username} to this repository\n\n\n\n\n\n\nNow, the Collaborator will follow this step:\n\nCheck your email for an invitation to GitHub or check your notifications (likely under “Your Organizations”) on GitHub to accept the invite to collaborate.\n\n\n\n\n\n\n\n\n\nLast thing, some Git configuration\n\n\n\nWhen Git released version 2.27, a new feature they incorporated allows users to specify how to pull, essentially, otherwise a warning will appear. To suppress this warning we need to configure our Git with this line of code:\ngit config pull.rebase false\npull.rebase false is a default strategy for pulling where it will try to auto-merge the files if possible, and if it can’t it will show a merge conflict\n\n\n\n\n\n\n\n\nInstructions\n\n\n\nYou will do the exercise twice, where each person will get to practice being both the Owner and the Collaborator roles.\n\nStep 0: Designate one person as the Owner and one as the Collaborator.\n\nRound One:\n\nStep 1: Owner adds Collaborator to {FIRSTNAME}_test repository (see Setup block above for detailed steps)\nStep 2: Collaborator clones the Owner’s {FIRSTNAME}_test repository\nStep 3: Collaborator edits the README file:\n\nCollaborator adds a new level 2 heading to README titled “Git Workflow”\n\nStep 4: Collaborator commits and pushes the README file with the new changes to GitHub\nStep 5: Owner pulls the changes that the Collaborator made\nStep 6: Owner edits the README file:\n\nUnder “Git Workflow”, Owner adds the steps of the Git workflow we’ve been practicing\n\nStep 7: Owner commits and pushes the README file with the new changes to GitHub\nStep 8: Collaborator pulls the Owners changes from GitHub\nStep 9: Go back to Step 0, switch roles, and then follow the steps in Round Two.\n\nRound Two:\n\nStep 1: Owner adds Collaborator to {FIRSTNAME}_test repository\nStep 2: Collaborator clones the Owner’s {FIRSTNAME}_test repository\nStep 3: Collaborator edits the README file:\n\nCollaborator adds a new level 2 heading to README titled “How to Create a Git Repository from an existing project” and adds the high level steps for this workflow\n\nStep 4: Collaborator commits and pushes the README file with the new changes to GitHub\nStep 5: Owner pulls the changes that the Collaborator made\nStep 6: Owner edits the README file:\n\nUnder “How to Create a Git Repository”, Owner adds the high level steps for this workflow\n\nStep 7: Owner commits and pushes the README file with the new changes to GitHub\nStep 8: Collaborator pulls the Owners changes from GitHub\n\nHint: If you don’t remember how to create a Git repository, refer to the chapter Intro to Git and GitHub where we created two Git repositories" + }, + { + "objectID": "session_01.html#a-note-on-advanced-collaboration-techniques", + "href": "session_01.html#a-note-on-advanced-collaboration-techniques", + "title": "1  Collaborating using Git and GitHub & Merge Conflicts", + "section": "1.4 A Note on Advanced Collaboration Techniques", + "text": "1.4 A Note on Advanced Collaboration Techniques\nThere are many Git and GitHub collaboration techniques, some more advanced than others. We won’t be covering advanced strategies in this course. But here is a table for your reference on a few popular Git collaboration workflow strategies and tools.\n\n\n\n\n\n\n\n\n\nCollaboration Technique\nBenefits\nWhen to Use\nWhen Not to Use\n\n\n\n\nBranch Management Strategies\n1. Enables parallel development and experimentation2. Facilitates isolation of features or bug fixes3. Provides flexibility and control over project workflows\nWhen working on larger projects with multiple features or bug fixes simultaneously.When you want to maintain a stable main branch while developing new features or resolving issues on separate branches.When collaborating with teammates on different aspects of a project and later integrating their changes.\nWhen working on small projects with a single developer or limited codebase.When the project scope is simple and doesn’t require extensive branch management.When there is no need to isolate features or bug fixes.\n\n\nCode Review Practices\n1. Enhances code quality and correctness through feedback2. Promotes knowledge sharing and learning within the team3. Helps identify bugs, improve performance, and ensure adherence to coding standards\nWhen collaborating on a codebase with team members to ensure code quality and maintain best practices.When you want to receive feedback and suggestions on your code to improve its readability, efficiency, or functionality.When working on critical or complex code that requires an extra layer of scrutiny before merging it into the main branch.\nWhen working on personal projects or small codebases with no collaboration involved.When time constraints or project size make it impractical to conduct code reviews.When the codebase is less critical or has low complexity.\n\n\nForking\n1. Enables independent experimentation and development2. Provides a way to contribute to a project without direct access3. Allows for creating separate, standalone copies of a repository\nWhen you want to contribute to a project without having direct write access to the original repository.When you want to work on an independent variation or extension of an existing project.When experimenting with changes or modifications to a project while keeping the original repository intact.\nWhen collaborating on a project with direct write access to the original repository.When the project does not allow external contributions or forking.When the project size or complexity doesn’t justify the need for independent variations.\n\n\nPull Requests\n1. Facilitates code review and discussion2. Allows for collaboration and feedback from team members3. Enables better organization and tracking of proposed changes\nWhen working on a shared repository with a team and wanting to contribute changes in a controlled and collaborative manner.When you want to propose changes to a project managed by others and seek review and approval before merging them into the main codebase.\nWhen working on personal projects or individual coding tasks without the need for collaboration.When immediate changes or fixes are required without review processes.When working on projects with a small team or single developer with direct write access to the repository.\n\n\n\nThe “When Not to Use” column provides insights into situations where it may be less appropriate to use each collaboration technique, helping you make informed decisions based on the specific context and requirements of your project.\nThese techniques provide different benefits and are used in various collaboration scenarios, depending on the project’s needs and team dynamics." + }, + { + "objectID": "session_01.html#merge-conflicts", + "href": "session_01.html#merge-conflicts", + "title": "1  Collaborating using Git and GitHub & Merge Conflicts", + "section": "1.5 Merge conflicts", + "text": "1.5 Merge conflicts\nMerge conflicts occur when both collaborators make conflicting changes to the same file. Resolving merge conflicts involves identifying the root of the problem and restoring the project to a normal state. Good communication, discussing file sections to work on, and avoiding overlaps can help prevent merge conflicts. However, if conflicts do arise, Git warns about potential issues and ensures that changes from different collaborators based on the same file version are not overwritten. To resolve conflicts, you need to explicitly specify whose changes should be used for each conflicting line in the file.\nIn this image, we see collaborators mbjones and metamattj have both made changes to the same line in the same README.md file. This is causing a merge conflict because Git doesn’t know whose changes came first. To resolve it, we need to tell Git whose changes to keep for that line, and whose changes to discard.\n\n\n1.5.1 Common ways to resolve a merge conflict\n1. Abort, abort, abort…\nSometimes you just made a mistake. When you get a merge conflict, the repository is placed in a “Merging” state until you resolve it. There’s a Terminal command to abort doing the merge altogether:\ngit merge --abort\nOf course, after doing that you still haven’t synced with your Collaborator’s changes, so things are still unresolved. But at least your repository is now usable on your local machine.\n2. Checkout\nThe simplest way to resolve a conflict, given that you know whose version of the file you want to keep, is to use the command line Git program to tell Git to use either your changes (the person doing the merge), or their changes (the Collaborator).\n\nkeep your Collaborator’s file: git checkout --theirs conflicted_file.Rmd\nkeep your own file: git checkout --ours conflicted_file.Rmd\n\nOnce you have run that command, then run add (staging), commit, pull, and push the changes as normal.\n3. Pull and edit the file\nBut that requires the command line. If you want to resolve from RStudio, or if you want to pick and choose some of your changes and some of your Collaborator’s, then instead you can manually edit and fix the file. When you pull the file with a conflict, Git notices that there is a conflict and modifies the file to show both your own changes and your Collaborator’s changes in the file. It also shows the file in the Git tab with an orange U icon, which indicates that the file is Unmerged, and therefore awaiting your help to resolve the conflict. It delimits these blocks with a series of less than and greater than signs, so they are easy to find:\n\n\n\n\n\nTo resolve the conflicts, simply find all of these blocks, and edit them so that the file looks how you want (either pick your lines, your Collaborator’s lines, some combination, or something altogether new), and save. Be sure you removed the delimiter lines that started with\n\n<<<<<<<,\n=======,\nand >>>>>>>.\n\nOnce you have made those changes, you simply add (staging), commit, and push the files to resolve the conflict." + }, + { + "objectID": "session_01.html#producing-and-resolving-merge-conflicts", + "href": "session_01.html#producing-and-resolving-merge-conflicts", + "title": "1  Collaborating using Git and GitHub & Merge Conflicts", + "section": "1.6 Producing and resolving merge conflicts", + "text": "1.6 Producing and resolving merge conflicts\nTo illustrate this process, the instructors are going to carefully create a merge conflict step by step, show how to resolve it, and show how to see the results of the successful merge after it is complete. First, the instructors will walk through the exercise to demonstrate the issues. Then, participants will pair up and try the exercise.\n\nStep 1: Owner and Collaborator ensure all changes are updated\nFirst, start the exercise by ensuring that both the Owner and Collaborator have all of the changes synced to their local copies of the Owner’s repository in RStudio. This includes doing a git pull to ensure that you have all changes local, and make sure that the Git tab in RStudio doesn’t show any changes needing to be committed.\n\n\nStep 2: Owner makes a change and commits\nFrom that clean slate, the Owner first modifies and commits a small change including their name on a specific line of the README.md file (we will change the first line, the title). Work to only change that one line, and add your username to the line in some form and commit the changes (but DO NOT push). We are now in a situation where the Owner has unpushed changes that the Collaborator can not yet see.\n\n\nStep 3: Collaborator makes a change and commits on the same line\nNow the Collaborator also makes changes to the same line (the first line, the title) on the README.md file in their RStudio copy of the project, adding their name to the line. They then commit. At this point, both the Owner and Collaborator have committed changes based on their shared version of the README.md file, but neither has tried to share their changes via GitHub.\n\n\nStep 4: Collaborator pushes the file to GitHub\nSharing starts when the Collaborator pushes their changes to the GitHub repo, which updates GitHub to their version of the file. The Owner is now one revision behind, but doesn’t know it yet.\n\n\nStep 5: Owner pushes their changes and gets an error\nAt this point, the Owner tries to push their change to the repository, which triggers an error from GitHub. While the error message is long, it basically tells you everything needed (that the Owner’s repository doesn’t reflect the changes on GitHub, and that they need to pull before they can push).\n\n\n\nStep 6: Owner pulls from GitHub to get Collaborator changes\nDoing what the message says, the Owner pulls the changes from GitHub, and gets another, different error message. In this case, it indicates that there is a merge conflict because of the conflicting lines.\n\nIn the Git pane of RStudio, the file is also flagged with an orange U, which stands for an unresolved merge conflict.\n\n\n\nStep 7: Owner edits the file to resolve the conflict\nTo resolve the conflict, the Owner now needs to edit the file. Again, as indicated above, Git has flagged the locations in the file where a conflict occurred with <<<<<<<, =======, and >>>>>>>. The Owner should edit the file, merging whatever changes are appropriate until the conflicting lines read how they should, and eliminate all of the marker lines with <<<<<<<, =======, and >>>>>>>.\n\nOf course, for scripts and programs, resolving the changes means more than just merging the text – whoever is doing the merging should make sure that the code runs properly and none of the logic of the program has been broken.\n\n\n\nStep 8: Owner commits the resolved changes\nFrom this point forward, things proceed as normal. The Owner first add the file changes to be made, which changes the orange U to a blue M for modified, and then commits the changes locally. The Owner now has a resolved version of the file on their system.\n\n\n\nStep 9: Owner pushes the resolved changes to GitHub\nHave the Owner push the changes, and it should replicate the changes to GitHub without error.\n\n\n\nStep 10: Collaborator pulls the resolved changes from GitHub\nFinally, the Collaborator can pull from GitHub to get the changes the Owner made.\n\n\nStep 11: Both can view commit history\nWhen either the Collaborator or the Owner view the history, the conflict, associated branch, and the merged changes are clearly visible in the history." + }, + { + "objectID": "session_01.html#exercise-2-with-a-partner-collaborate-in-a-repository-and-resolve-a-merge-conflict", + "href": "session_01.html#exercise-2-with-a-partner-collaborate-in-a-repository-and-resolve-a-merge-conflict", + "title": "1  Collaborating using Git and GitHub & Merge Conflicts", + "section": "1.7 Exercise 2: With a partner collaborate in a repository and resolve a merge conflict", + "text": "1.7 Exercise 2: With a partner collaborate in a repository and resolve a merge conflict\nNote you will only need to complete the Setup and Git configuration steps again if you are working in a new repository. Return to Exercise 1 for Setup and Git configuration steps.\n\n\n\n\n\n\nInstructions\n\n\n\nNow it’s your turn. In pairs, intentionally create a merge conflict, and then go through the steps needed to resolve the issues and continue developing with the merged files. See the sections above for help with each of the steps below. You will do the exercise twice, where each person will get to practice being both the Owner and the Collaborator roles.\n\nStep 0: Designate one person as the Owner and one as the Collaborator.\n\nRound One:\n\nStep 1: Both Owner and Collaborator pull to ensure both have the most up-to-date changes\nStep 2: Owner edits the README file and makes a change to the title and commits do not push\nStep 3: On the same line, Collaborator edits the README file and makes a change to the title and commits\nStep 4: Collaborator pushes the file to GitHub\nStep 5: Owner pushes their changes and gets an error\nStep 6: Owner pulls from GitHub to get Collaborator changes\nStep 7: Owner edits the README file to resolve the conflict\nStep 8: Owner commits the resolved changes\nStep 9: Owner pushes the resolved changes to GitHub\nStep 10: Collaborator pulls the resolved changes from GitHub\nStep 11: Both view commit history\nStep 12: Go back to Step 0, switch roles, and then follow the steps in Round Two.\n\nRound Two:\n\nStep 1: Both Owner and Collaborator pull to ensure both have the most up-to-date changes\nStep 2: Owner edits the README file and makes a change to line 2 and commits do not push\nStep 3: On the same line, Collaborator edits the README file and makes a change to line 2 and commits\nStep 4: Collaborator pushes the file to GitHub\nStep 5: Owner pushes their changes and gets an error\nStep 6: Owner pulls from GitHub to get Collaborator changes\nStep 7: Owner edits the README file to resolve the conflict\nStep 8: Owner commits the resolved changes\nStep 9: Owner pushes the resolved changes to GitHub\nStep 10: Collaborator pulls the resolved changes from GitHub\nStep 11: Both view commit history" + }, + { + "objectID": "session_01.html#best-practices-to-avoid-merge-conflicts", + "href": "session_01.html#best-practices-to-avoid-merge-conflicts", + "title": "1  Collaborating using Git and GitHub & Merge Conflicts", + "section": "1.8 Best practices to avoid merge conflicts", + "text": "1.8 Best practices to avoid merge conflicts\nSome basic rules of thumb can avoid the vast majority of merge conflicts, saving a lot of time and frustration. These are words our teams live by:\n\n\n\n\n\nXKCD 1597\n\n\n\nCommunicate often and set up effective communication channels\nTell each other what you are working on\nStart your working session with a pull\nPull immediately before you commit or push\nCommit often in small chunks (this helps you organize your work!)\nMake sure you and who you are collaborating with all fully understand the Git workflow you’re using aka make sure you’re on the same page before you start!\n\nA good workflow is encapsulated as follows:\nPull -> Edit -> Save -> Add (stage) -> Commit -> Pull -> Push\nAlways start your working sessions with a pull to get any outstanding changes, then start your work. Stage your changes, but before you commit, pull again to see if any new changes have arrived. If so, they should merge in easily if you are working in different parts of the program. You can then commit and immediately push your changes safely.\nGood luck, and try to not get frustrated. Once you figure out how to handle merge conflicts, they can be avoided or dispatched when they occur, but it does take a bit of practice." + }, + { + "objectID": "session_02.html#developing-a-code-of-conduct", + "href": "session_02.html#developing-a-code-of-conduct", + "title": "2  Social Aspects of Collaboration", + "section": "2.1 Developing a Code of Conduct", + "text": "2.1 Developing a Code of Conduct\nWhether you are joining a lab group or establishing a new collaboration, articulating a set of shared agreements about how people in the group will treat each other will help create the conditions for successful collaboration. If agreements or a code of conduct do not yet exist, invite a conversation among all members to create them. Co-creation of a code of conduct will foster collaboration and engagement as a process in and of itself, and is important to ensure all voices heard such that your code of conduct represents the perspectives of your community. If a code of conduct already exists, and your community will be a long-acting collaboration, you might consider revising the code of conduct. Having your group ‘sign off’ on the code of conduct, whether revised or not, supports adoption of the principles.\nWhen creating a code of conduct, consider both the behaviors you want to encourage and those that will not be tolerated. For example, the Openscapes code of conduct includes Be respectful, honest, inclusive, accommodating, appreciative, and open to learning from everyone else. Do not attack, demean, disrupt, harass, or threaten others or encourage such behavior.\nBelow are other example codes of conduct:\n\nNCEAS Code of Conduct\nCarpentries Code of Conduct\nArctic Data Center Code of Conduct\nMozilla Community Participation Guidelines\nEcological Society of America Code of Conduct" + }, + { + "objectID": "session_02.html#authorship-and-credit-policies", + "href": "session_02.html#authorship-and-credit-policies", + "title": "2  Social Aspects of Collaboration", + "section": "2.2 Authorship and Credit Policies", + "text": "2.2 Authorship and Credit Policies\n\nNavigating issues of intellectual property and credit can be a challenge, particularly for early career researchers. Open communication is critical to avoiding misunderstandings and conflicts. Talk to your coauthors and collaborators about authorship, credit, and data sharing early and often. This is particularly important when working with new collaborators and across lab groups or disciplines which may have divergent views on authorship and data sharing. If you feel uncomfortable talking about issues surrounding credit or intellectual property, seek the advice or assistance of a mentor to support you in having these important conversations.\nThe “Publication” section of the Ecological Society of America’s Code of Ethics is a useful starting point for discussions about co-authorship, as are the International Committee of Medical Journal Editors guidelines for authorship and contribution. You should also check guidelines published by the journal(s) to which you anticipate submitting your work.\nFor collaborative research projects, develop an authorship agreement for your group early in the project and refer to it for each product. This example authorship agreement from the Arctic Data Center provides a useful template. It builds from information contained within Weltzin et al (2006) and provides a rubric for inclusion of individuals as authors. Your collaborative team may not choose to adopt the agreement in the current form, however it will prompt thought and discussion in advance of developing a consensus. Some key questions to consider as you are working with your team to develop the agreement:\n\nWhat roles do we anticipate contributors will play? e.g., the NISO Contributor Roles Taxonomy (CRediT) identifies 14 distinct roles:\n\nConceptualization\nData curation\nFormal Analysis\nFunding acquisition\nInvestigation\nMethodology\nProject administration\nResources\nSoftware\nSupervision\nValidation\nVisualization\nWriting – original draft\nWriting – review & editing\n\nWhat are our criteria for authorship? (See the ICMJE guidelines for potential criteria)\nWill we extend the opportunity for authorship to all group members on every paper or product?\nDo we want to have an opt in or opt out policy? (In an opt out policy, all group members are considered authors from the outset and must request removal from the paper if they don’t want think they meet the criteria for authorship)\nWho has the authority to make decisions about authorship? Lead author? PI? Group?\nHow will we decide authorship order?\nIn what other ways will we acknowledge contributions and extend credit to collaborators?\nHow will we resolve conflicts if they arise?" + }, + { + "objectID": "session_02.html#data-sharing-and-reuse-policies", + "href": "session_02.html#data-sharing-and-reuse-policies", + "title": "2  Social Aspects of Collaboration", + "section": "2.3 Data Sharing and Reuse Policies", + "text": "2.3 Data Sharing and Reuse Policies\nAs with authorship agreements, it is valuable to establish a shared agreement around handling of data when embarking on collaborative projects. Data collected as part of a funded research activity will typically have been managed as part of the Data Management Plan (DMP) associated with that project. However, collaborative research brings together data from across research projects with different data management plans and can include publicly accessible data from repositories where no management plan is available. For these reasons, a discussion and agreement around the handling of data brought into and resulting from the collaboration is warranted and management of this new data may benefit from going through a data management planning process. Below we discuss example data agreements.\nThe example data policy template provided by the Arctic Data Center addresses three categories of data.\n\nIndividual data not in the public domain\nIndividual data with public access\nDerived data resulting from the project\n\nFor the first category, the agreement considers conditions under which those data may be used and permissions associated with use. It also addresses access and sharing. In the case of individual, publicly accessible data, the agreement stipulates that the team will abide by the attribution and usage policies that the data were published under, noting how those requirements we met. In the case of derived data, the agreement reads similar to a DMP with consideration of making the data public; management, documentation and archiving; pre-publication sharing; and public sharing and attribution. As research data objects receive a persistent identifier (PID), often a DOI, there are citable objects and consideration should be given to authorship of data, as with articles.\nThe following example lab policy from the Wolkovich Lab combines data management practices with authorship guidelines and data sharing agreements. It provides a lot of detail about how this lab approaches data use, attribution and authorship. For example:\n\nSection 6: Co-authorship & data\nIf you agree to take on existing data you cannot offer co-authorship for use of the data unless four criteria are met:\n\nThe co-author agrees to (and does) make substantial intellectual contribution to the work, which includes the reading and editing of all manuscripts on which you are a co-author through the submission-for-publication stage. This includes helping with interpretation of the data, system, study questions.\nAgreement of co-authorship is made at the start of the project.\nAgreement is approved of by Lizzie.\nAll data-sharers are given an equal opportunity at authorship. It is not allowed to offer or give authorship to one data-sharer unless all other data-sharers are offered an equal opportunity at authorship—this includes data that are publicly-available, meaning if you offer authorship to one data-sharer and were planning to use publicly-available data you must reach out to the owner of the publicly-available data and strongly offer equivalent authorship as offered to the other data-sharer. As an example, if five people share data freely with you for a meta-analysis and and a sixth wants authorship you either must strongly offer equivalent authorship to all five or deny authorship to the sixth person. Note that the above requirements must also be met in this situation. If one or more datasets are more central or critical to a paper to warrant selective authorship this must be discussed and approved by Lizzie (and has not, to date, occurred within the lab).\n\n\n\n\n\n\n2.3.0.1 Policy Preview\n\n\nThis policy is communicated with all incoming lab members, from undergraduate to postdocs and visiting scholars, and is shared here with permission from Dr Elizabeth Wolkovich.\n\n\n2.3.1 Community Principles: CARE and FAIR\nThe CARE and FAIR Principles were introduced previously in the context of introducing the Arctic Data Center and our data submission and documentation process. In this section we will dive a little deeper.\nTo recap, the Arctic Data Center is an openly-accessible data repository and the data published through the repository is open for anyone to reuse, subject to conditions of the license (at the Arctic Data Center, data is released under one of two licenses: CC-0 Public Domain and CC-By Attribution 4.0). In facilitating use of data resources, the data stewardship community have converged on principles surrounding best practices for open data management One set of these principles is the FAIR principles. FAIR stands for Findable, Accessible, Interoperable, and Reproducible.\n\nThe “Fostering FAIR Data Practices in Europe” project found that it is more monetarily and timely expensive when FAIR principles are not used, and it was estimated that 10.2 billion dollars per years are spent through “storage and license costs to more qualitative costs related to the time spent by researchers on creation, collection and management of data, and the risks of research duplication.” FAIR principles and open science are overlapping concepts, but are distinctive concepts. Open science supports a culture of sharing research outputs and data, and FAIR focuses on how to prepare the data.\n\nAnother set of community developed principles surrounding open data are the CARE Principles. The CARE principles for Indigenous Data Governance complement the more data-centric approach of the FAIR principles, introducing social responsibility to open data management practices. The CARE Principles stand for:\n\nCollective Benefit - Data ecosystems shall be designed and function in ways that enable Indigenous Peoples to derive benefit from the data\nAuthority to Control - Indigenous Peoples’ rights and interests in Indigenous data must be recognised and their authority to control such data be empowered. Indigenous data governance enables Indigenous Peoples and governing bodies to determine how Indigenous Peoples, as well as Indigenous lands, territories, resources, knowledges and geographical indicators, are represented and identified within data.\nResponsibility - Those working with Indigenous data have a responsibility to share how those data are used to support Indigenous Peoples’ self-determination and collective benefit. Accountability requires meaningful and openly available evidence of these efforts and the benefits accruing to Indigenous Peoples.\nEthics - Indigenous Peoples’ rights and wellbeing should be the primary concern at all stages of the data life cycle and across the data ecosystem.\n\nThe CARE principles align with the FAIR principles by outlining guidelines for publishing data that is findable, accessible, interoperable, and reproducible while at the same time, accounts for Indigenous’ Peoples rights and interests. Initially designed to support Indigenous data sovereignty, CARE principles are now being adopted across domains, and many researchers argue they are relevant for both Indigenous Knowledge and data, as well as data from all disciplines (Carroll et al., 2021). These principles introduce a “game changing perspective” that encourages transparency in data ethics, and encourages data reuse that is purposeful and intentional that aligns with human well-being aligns with human well-being (Carroll et al., 2021)." + }, + { + "objectID": "session_02.html#research-data-publishing-ethics", + "href": "session_02.html#research-data-publishing-ethics", + "title": "2  Social Aspects of Collaboration", + "section": "2.4 Research Data Publishing Ethics", + "text": "2.4 Research Data Publishing Ethics\nFor over 20 years, the Committee on Publication Ethics (COPE) has provided trusted guidance on ethical practices for scholarly publishing. The COPE guidelines have been broadly adopted by academic publishers across disciplines, and represent a common approach to identify, classify, and adjudicate potential breaches of ethics in publication such as authorship conflicts, peer review manipulation, and falsified findings, among many other areas. Despite these guidelines, there has been a lack of ethics standards, guidelines, or recommendations for data publications, even while some groups have begun to evaluate and act upon reported issues in data publication ethics.\n\n\n\nData retractions\n\n\nTo address this gap, the Force 11 Working Group on Research Data Publishing Ethics was formed as a collaboration among research data professionals and the Committee on Publication Ethics (COPE) “to develop industry-leading guidance and recommended best practices to support repositories, journal publishers, and institutions in handling the ethical responsibilities associated with publishing research data.” The group released the “Joint FORCE11 & COPE Research Data Publishing Ethics Working Group Recommendations” (Puebla, Lowenberg, and WG 2021), which outlines recommendations for four categories of potential data ethics issues:\n\n\n\nForce11/COPE\n\n\n\nAuthorship and Contribution Conflicts\n\nAuthorship omissions\nAuthorship ordering changes / conflicts\nInstitutional investigation of author finds misconduct\n\nLegal/regulatory restrictions\n\nCopyright violation\nInsufficient rights for deposit\nBreaches of national privacy laws (GPDR, CCPA)\nBreaches of biosafety and biosecurity protocols\nBreaches of contract law governing data redistribution\n\nRisks of publication or release\n\nRisks to human subjects\n\nLack of consent\nBreaches of himan rights\nRelease of personally identifiable information (PII)\n\nRisks to species, ecosystems, historical sites\n\nLocations of endangered species or historical sites\n\nRisks to communities or societies\n\nData harvested for profit or surveillance\nBreaches of data sovereignty\n\n\nRigor of published data\n\nUnintentional errors in collection, calculation, display\nUn-interpretable data due to lack of adequate documentation\nErrors of of study design and inference\nData manipulation or fabrication\n\n\nGuidelines cover what actions need to be taken, depending on whether the data are already published or not, as well as who should be involved in decisions, who should be notified of actions, and when the public should be notified. The group has also published templates for use by publishers and repositories to announce the extent to which they plan to conform to the data ethics guidelines.\n\nDiscussion: Data publishing policies\nAt the Arctic Data Center, we need to develop policies and procedures governing how we react to potential breaches of data publication ethics. In this exercise, break into groups to provide advice on how the Arctic Data Center should respond to reports of data ethics issues, and whether we should adopt the Joint FORCE11 & COPE Research Data Publishing Ethics Working Group Policy Templates for repositories. In your discussion, consider:\n\nShould the repository adopt the repository policy templates from Force11?\nWho should be involved in evaluation of the merits of ethical cases reported to ADC?\nWho should be involved in deciding the actions to take?\nWhat are the range of responses that the repository should consider for ethical breaches?\nWho should be notified when a determination has been made that a breach has occurred?\n\nYou might consider a hypothetical scenario such as the following in considering your response.\n\nThe data coordinator at the Arctic Data Center receives an email in 2022 from a prior postdoctoral fellow who was employed as part of an NSF-funded project on microbial diversity in Alaskan tundra ecosystems. The email states that a dataset from 2014 in the Arctic Data Center was published with the project PI as author, but omits two people, the postdoc and an undergraduate student, as co-authors on the dataset. The PI retired in 2019, and the postdoc asks that they be added to the author list of the dataset to correct the historical record and provide credit." + }, + { + "objectID": "session_02.html#extra-reading", + "href": "session_02.html#extra-reading", + "title": "2  Social Aspects of Collaboration", + "section": "2.5 Extra Reading", + "text": "2.5 Extra Reading\n\nCheruvelil, K. S., Soranno, P. A., Weathers, K. C., Hanson, P. C., Goring, S. J., Filstrup, C. T., & Read, E. K. (2014). Creating and maintaining high-performing collaborative research teams: The importance of diversity and interpersonal skills. Frontiers in Ecology and the Environment, 12(1), 31-38. DOI: 10.1890/130001\nCarroll, S. R., Garba, I., Figueroa-Rodríguez, O. L., Holbrook, J., Lovett, R., Materechera, S., … Hudson, M. (2020). The CARE Principles for Indigenous Data Governance. Data Science Journal, 19(1), 43. DOI: http://doi.org/10.5334/dsj-2020-043\n\n\n\n\n\nPuebla, Iratxe, Daniella Lowenberg, and FORCE11 Research Data Publishing Ethics WG. 2021. “Joint FORCE11 & COPE Research Data Publishing Ethics Working Group Recommendations.” Zenodo. https://doi.org/10.5281/zenodo.5391293." + }, + { + "objectID": "session_03.html", + "href": "session_03.html", + "title": "3  Thinking Preferences", + "section": "", + "text": "INSERT ONE OF THE THIKING PREFERENCES VERSIONS" + }, + { + "objectID": "session_05.html#learning-objectives", + "href": "session_05.html#learning-objectives", + "title": "5  Publishing your Analysis to the Web", + "section": "Learning Objectives", + "text": "Learning Objectives\n\nHow to use Git, GitHub (+Pages), and R Markdown to publish an analysis to the web" + }, + { + "objectID": "session_05.html#introduction", + "href": "session_05.html#introduction", + "title": "5  Publishing your Analysis to the Web", + "section": "5.1 Introduction", + "text": "5.1 Introduction\nSharing your work with others in engaging ways is an important part of the scientific process.\nSo far in this course, we’ve introduced a small set of powerful tools for doing open science:\n\nR and its many packages\nRStudio\nGit\nGitHub\nR Markdown\n\nR Markdown, in particular, is amazingly powerful for creating scientific reports but, so far, we haven’t tapped its full potential for sharing our work with others.\nIn this lesson, we’re going to take our training_{USERNAME} GitHub repository and turn it into a beautiful and easy to read web page using the tools listed above.\n\n\n\n\n\n\nSet up\n\n\n\n\nMake sure you are in training_{USERNAME} project\nAdd a new R Markdown file at the top level called index.Rmd\n\nGo to the RStudio menu File > New File > R Markdown\nThis will bring up a dialog box. Add the title “GitHub Pages Example”, keep the Default Output Format as “HTML”, and then click “OK”\n\nSave the R Markdown file you just created. Use index.Rmd as the file name\n\nBe sure to use the exact case (lower case ‘index’) as different operating systems handle case differently and it can interfere with loading your web page later\n\nPress “Knit” and observe the rendered output\n\nNotice the new file in the same directory index.html\nThis is our R Markdown file rendered as HTML (a web page)\n\nCommit your changes (for both index.Rmd and index.html) with a commit message, and push to GitHub\nOpen your web browser to the GitHub.com and navigate to the page for your training_{USERNAME} repository\nActivate GitHub Pages for the main branch\n\nGo to Settings > Pages (underneath the Code and Automation section)\nKeep the “Source” as “Deploy from a branch”\nUnder “Branch” you’ll see a message that says “GitHub Pages is currently disabled”. To change this, change the branch from “None” to main. Keep the folder as the root and then click “Save”\nYou should see the message change to “Your GitHub Pages site is currently being built from the main branch”\n\n\nNote: index.Rmd represents the default file for a web site, and is returned whenever you visit the web site but doesn’t specify an explicit file to be returned.\n\n\nNow, the rendered website version of your repo will show up at a special URL.\nGitHub Pages follows a convention like this:\n\nNote that it changes from github.com to github.io\n\nGo to https://{username}.github.io/{repo_name}/ (Note the trailing /)\nObserve the awesome rendered output\n\nNow that we’ve successfully published a web page from an R Markdown document, let’s make a change to our R Markdown document and follow the steps to publish the change on the web:\n\n\n\n\n\n\nUpdate content in your published page\n\n\n\n\nGo back to your index.Rmd\nDelete all the content, except the YAML frontmatter\nType “Hello world”\nUse Git workflow: Stage > Commit > Pull > Push\nGo back to https://{username}.github.io/{repo_name}/\n\n\n\nNext, we will show how you can link different Rmds rendered into html so you can easily share different parts of your work.\n\n\n\n\n\n\nExercise\n\n\n\nIn this exercise, you’ll create a table of contents with the lessons of this course on the main page, and link some of the files we have work on so far.\n\nGo back to the RStudio server and to your index.Rmd file\nCreate a table of contents with the names of the main technical lessons of this course, like so:\n\n## coreR workshop\n\n- Introduction to RMarkdown \n- Cleaning and Wrangling data\n- Data Visualization\n- Spatial Analysis\n\nMake sure you have the html versions of your intro-to-rmd.Rmd and data-cleaning.Rmd files. If you only see the Rmd version, you need to “Knit” your files first\nIn your index.Rmd let’s add the links to the html files we want to show on our webpage. Do you remember the Markdown syntax to create a link?\n\n\n\nMarkdown syntax to create a link:\n\n\n[Text you want to hyperlink](link)\n\nExample: [Data wrangling and cleaning](data-wrangling-cleaning.html)\n\n\n\n\nUse Git workflow: Stage > Commit > Pull > Push\n\nNow when you visit your web site, you’ll see the table of contents, and can navigate to the others file you linked.\n\n\nR Markdown web pages are a great way to share work in progress with your colleagues. Here we showed an example with the materials we have created in this course. However, you can use these same steps to share the different files and progress of a project you’ve been working on. To do so simply requires thinking through your presentation so that it highlights the workflow to be reviewed. You can include multiple pages and build a simple web site and make your work accessible to people who aren’t set up to open your project in R. Your site could look something like this:" + }, + { + "objectID": "session_06.html#learning-objectives", + "href": "session_06.html#learning-objectives", + "title": "6  Data Visualization in R", + "section": "Learning Objectives", + "text": "Learning Objectives\n\nThe basics of the ggplot2 package to create static plots\nHow to use ggplot2’s theme abilities to create publication-grade graphics\nThe basics of the leaflet package to create interactive maps" + }, + { + "objectID": "session_06.html#overview", + "href": "session_06.html#overview", + "title": "6  Data Visualization in R", + "section": "6.1 Overview", + "text": "6.1 Overview\nggplot2 is a popular package for visualizing data in R. From the home page:\n\nggplot2 is a system for declaratively creating graphics, based on The Grammar of Graphics. You provide the data, tell ggplot2 how to map variables to aesthetics, what graphical primitives to use, and it takes care of the details.\n\nIt’s been around for years and has pretty good documentation and tons of example code around the web (like on StackOverflow). The goal of this lesson is to introduce you to the basic components of working with ggplot2 and inspire you to go and explore this awesome resource for visualizing your data.\n\n\n\n\n\n\nggplot2 vs base graphics in R vs others\n\n\n\nThere are many different ways to plot your data in R. All of them work! However, ggplot2 excels at making complicated plots easy and easy plots simple enough\nBase R graphics (plot(), hist(), etc) can be helpful for simple, quick and dirty plots. ggplot2 can be used for almost everything else.\n\n\nLet’s dive into creating and customizing plots with ggplot2.\n\n\n\n\n\n\nSetup\n\n\n\n\nMake sure you’re in the right project (training_{USERNAME}) and use the Git workflow by Pulling to check for any changes. Then, create a new R Markdown document and remove the default text.\nLoad the packages we’ll need:\n\n\nlibrary(readr)\nlibrary(dplyr)\nlibrary(tidyr)\nlibrary(forcats)\nlibrary(ggplot2)\nlibrary(leaflet)\nlibrary(DT)\nlibrary(scales)\n\n\nLoad the data table directly from the KNB Data Repository: Daily salmon escapement counts from the OceanAK database, Alaska, 1921-2017. Navegate to the link above, hover over the “Download” button for the ADFG_fisrtAttempt_reformatted.csv, right click, and select “Copy Link”.\n\n\nescape <- read_csv(\"https://knb.ecoinformatics.org/knb/d1/mn/v2/object/urn%3Auuid%3Af119a05b-bbe7-4aea-93c6-85434dcb1c5e\")\n\n\nLearn about the data. For this session we are going to be working with data on daily salmon escapement counts in Alaska. Check out the documentation.\nFinally, let’s explore the data we just read into our working environment.\n\n\n## Check out column names\ncolnames(escape)\n\n## Peak at each column and class\nglimpse(escape)\n\n## From when to when\nrange(escape$sampleDate)\n\n## How frequent?\nhead(escape$sampleDate)\ntail(escape$sampleDate)\n\n## Which species?\nunique(escape$Species)" + }, + { + "objectID": "session_06.html#getting-the-data-ready", + "href": "session_06.html#getting-the-data-ready", + "title": "6  Data Visualization in R", + "section": "6.2 Getting the data ready", + "text": "6.2 Getting the data ready\nIt is more frequent than not, that we need to do some wrangling before we can plot our data the way we want to. Now that we have read out data and have done some exploration, we’ll put our data wrangling skills to practice to get our data in the desired format.\n\n\n\n\n\n\nExercise\n\n\n\n\nCalculate the annual escapement by Species and SASAP.Region,\nFilter the main 5 salmon species (Chinook, Sockeye, Chum, Coho and Pink)\n\n\n\n\nannual_esc <- escape %>%\n separate(sampleDate, c(\"Year\", \"Month\", \"Day\"), sep = \"-\") %>%\n mutate(Year = as.numeric(Year)) %>%\n group_by(Species, SASAP.Region, Year) %>%\n summarize(escapement = sum(DailyCount)) %>%\n filter(Species %in% c(\"Chinook\", \"Sockeye\", \"Chum\", \"Coho\", \"Pink\"))\n\nhead(annual_esc)\n\n# A tibble: 6 × 4\n# Groups: Species, SASAP.Region [1]\n Species SASAP.Region Year escapement\n <chr> <chr> <dbl> <dbl>\n1 Chinook Alaska Peninsula and Aleutian Islands 1974 1092\n2 Chinook Alaska Peninsula and Aleutian Islands 1975 1917\n3 Chinook Alaska Peninsula and Aleutian Islands 1976 3045\n4 Chinook Alaska Peninsula and Aleutian Islands 1977 4844\n5 Chinook Alaska Peninsula and Aleutian Islands 1978 3901\n6 Chinook Alaska Peninsula and Aleutian Islands 1979 10463\n\n\nThe chunk above used a lot of the dplyr commands that we’ve used, and some that are new. The separate() function is used to divide the sampleDate column up into Year, Month, and Day columns, and then we use group_by() to indicate that we want to calculate our results for the unique combinations of species, region, and year. We next use summarize() to calculate an escapement value for each of these groups. Finally, we use a filter and the %in% operator to select only the salmon species." + }, + { + "objectID": "session_06.html#plotting-with-ggplot2", + "href": "session_06.html#plotting-with-ggplot2", + "title": "6  Data Visualization in R", + "section": "6.3 Plotting with ggplot2", + "text": "6.3 Plotting with ggplot2\n\n6.3.1 Essentials components\nFirst, we’ll cover some ggplot2 basics to create the foundation of our plot. Then, we’ll add on to make our great customized data visualization.\n\n\n\n\n\n\nThe basics\n\n\n\n\nIndicate we are using ggplot() (call the ggplot2::ggplot() function)\nWhat data do we want to plot? (data = my_data)\nWhat is my mapping aesthetics? What variables do we want to plot? (define usingaes() function)\nDefine the geometry of our plot. This specifies the type of plot we’re making (use geom_*() to indicate the type of plot e.g: point, bar, etc.)\n\nNote To add layers to our plot, for example, additional geometries/aesthetics and theme elements or any ggplot object we use +.\n\n\nFor example, let’s plot total escapement by species. We will show this by creating the same plot in 3 slightly different ways. Each of the options below have the essential pieces of a ggplot.\n\n## Option 1 - data and mapping called in the ggplot() function\nggplot(data = annual_esc,\n aes(x = Species, y = escapement)) +\n geom_col()\n\n## Option 2 - data called in ggplot function; mapping called in geom\nggplot(data = annual_esc) +\n geom_col(aes(x = Species, y = escapement))\n\n\n## Option 3 - data and mapping called in geom\nggplot() +\n geom_col(data = annual_esc,\n aes(x = Species, y = escapement))\n\nThey all will create the same plot:\n\n\n\n\n\n\n\n6.3.2 Looking at different geoms\nHaving the basic structure with the essential components in mind, we can easily change the type of graph by updating the geom_*().\n\n\n\n\n\n\nggplot2 and the pipe operator\n\n\n\nJust like in dplyr and tidyr, we can also pipe a data.frame directly into the first argument of the ggplot function using the %>% operator.\nThis can certainly be convenient, but use it carefully! Combining too many data-tidying or subsetting operations with your ggplot call can make your code more difficult to debug and understand.\n\n\nNext, we will use the pipe operator to pass into ggplot() a filtered version of annual_esc, and make a plot with different geometries.\nBoxplot\n\nannual_esc %>%\n filter(Year == 1974,\n Species %in% c(\"Chum\", \"Pink\")) %>%\n ggplot(aes(x = Species, y = escapement)) +\n geom_boxplot()\n\n\n\n\nViolin plot\n\nannual_esc %>%\n filter(Year == 1974,\n Species %in% c(\"Chum\", \"Pink\")) %>%\n ggplot(aes(x = Species, y = escapement)) +\n geom_violin()\n\n\n\n\nLine and point\n\nannual_esc %>%\n filter(Species == \"Sockeye\",\n SASAP.Region == \"Bristol Bay\") %>%\n ggplot(aes(x = Year, y = escapement)) +\n geom_line() +\n geom_point()\n\n\n\n\n\n\n6.3.3 Customizing our plot\nLet’s go back to our base bar graph. What if we want our bars to be blue instead of gray? You might think we could run this:\n\nggplot(annual_esc,\n aes(x = Species, y = escapement,\n fill = \"blue\")) +\n geom_col()\n\n\n\n\nWhy did that happen?\nNotice that we tried to set the fill color of the plot inside the mapping aesthetic call. What we have done, behind the scenes, is create a column filled with the word “blue” in our data frame, and then mapped it to the fill aesthetic, which then chose the default fill color of red.\nWhat we really wanted to do was just change the color of the bars. If we want do do that, we can call the color option in the geom_col() function, outside of the mapping aesthetics function call.\n\nggplot(annual_esc,\n aes(x = Species, y = escapement)) +\n geom_col(fill = \"blue\")\n\n\n\n\nWhat if we did want to map the color of the bars to a variable, such as region. ggplot() is really powerful because we can easily get this plot to visualize more aspects of our data.\n\nggplot(annual_esc,\n aes(x = Species, y = escapement,\n fill = SASAP.Region)) +\n geom_col()\n\n\n\n\n\n\n\n\n\n\nKeep in mind\n\n\n\n\nIf you want to map a variable onto a graph aesthetic (e.g., point color should be based on a specific region), put it within aes().\nIf you want to update your plot base on a constant (e.g. “Make ALL the points BLUE”), you can add the information directly to the relevant geom_ layer.\n\n\n\n\n6.3.3.1 Creating multiple plots\nWe know that in the graph we just plotted, each bar includes escapements for multiple years. Let’s leverage the power of ggplot to plot more aspects of our data in one plot.\nWe are going to plot escapement by species over time, from 2000 to 2016, for each region.\nAn easy way to plot another aspect of your data is using the function facet_wrap(). This function takes a mapping to a variable using the syntax ~{variable_name}. The ~ (tilde) is a model operator which tells facet_wrap() to model each unique value within variable_name to a facet in the plot.\nThe default behavior of facet wrap is to put all facets on the same x and y scale. You can use the scales argument to specify whether to allow different scales between facet plots (e.g scales = \"free_y\" to free the y axis scale). You can also specify the number of columns using the ncol = argument or number of rows using nrow =.\n\n## Subset with data from years 2000 to 2016\n\nannual_esc_2000s <- annual_esc %>%\n filter(Year %in% c(2000:2016))\n\n## Quick check\nunique(annual_esc_2000s$Year)\n\n [1] 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014\n[16] 2015 2016\n\n## Plot with facets\nggplot(annual_esc_2000s,\n aes(x = Year,\n y = escapement,\n color = Species)) +\n geom_line() +\n geom_point() +\n facet_wrap( ~ SASAP.Region,\n scales = \"free_y\")\n\n\n\n\n\n\n6.3.3.2 Setting ggplot themes\nNow let’s work on making this plot look a bit nicer. We are going to”\n\nAdd a title using ggtitle()\nAdjust labels using ylab()\nInclude a built in theme using theme_bw()\n\nThere are a wide variety of built in themes in ggplot that help quickly set the look of the plot. Use the RStudio autocomplete theme_ <TAB> to view a list of theme functions.\n\nggplot(annual_esc_2000s,\n aes(x = Year,\n y = escapement,\n color = Species)) +\n geom_line() +\n geom_point() +\n facet_wrap( ~ SASAP.Region,\n scales = \"free_y\") +\n ylab(\"Escapement\") +\n ggtitle(\"Annual Salmon Escapement by Region\") +\n theme_bw()\n\n\n\n\nYou can see that the theme_bw() function changed a lot of the aspects of our plot! The background is white, the grid is a different color, etc. There are lots of other built in themes like this that come with the ggplot2 package.\n\n\n\n\n\n\nExercise\n\n\n\nUse the RStudio auto complete, the ggplot2 documentation, a cheat sheet, or good old Google to find other built in themes. Pick out your favorite one and add it to your plot.\n\n\n\n\nThemes\n## Useful baseline themes are\ntheme_minimal()\ntheme_light()\ntheme_classic()\n\n\nThe built in theme functions (theme_*()) change the default settings for many elements that can also be changed individually using thetheme() function. The theme() function is a way to further fine-tune the look of your plot. This function takes MANY arguments (just have a look at ?theme). Luckily there are many great ggplot resources online so we don’t have to remember all of these, just Google “ggplot cheat sheet” and find one you like.\nLet’s look at an example of a theme() call, where we change the position of the legend from the right side to the bottom, and remove its title.\n\nggplot(annual_esc_2000s,\n aes(x = Year,\n y = escapement,\n color = Species)) +\n geom_line() +\n geom_point() +\n facet_wrap( ~ SASAP.Region,\n scales = \"free_y\") +\n ylab(\"Escapement\") +\n ggtitle(\"Annual Salmon Escapement by Region\") +\n theme_light() +\n theme(legend.position = \"bottom\",\n legend.title = element_blank())\n\n\n\n\nNote that the theme() call needs to come after any built-in themes like theme_bw() are used. Otherwise, theme_bw() will likely override any theme elements that you changed using theme().\nYou can also save the result of a series of theme() function calls to an object to use on multiple plots. This prevents needing to copy paste the same lines over and over again!\n\nmy_theme <- theme_light() +\n theme(legend.position = \"bottom\",\n legend.title = element_blank())\n\nSo now our code will look like this:\n\nggplot(annual_esc_2000s,\n aes(x = Year,\n y = escapement,\n color = Species)) +\n geom_line() +\n geom_point() +\n facet_wrap( ~ SASAP.Region,\n scales = \"free_y\") +\n ylab(\"Escapement\") +\n ggtitle(\"Annual Salmon Escapement by Region\") +\n my_theme\n\n\n\n\n\n\n\n\n\n\nExercise\n\n\n\n\nUsing whatever method you like, figure out how to rotate the x-axis tick labels to a 45 degree angle.\n\nHint: You can start by looking at the documentation of the function by typing ?theme() in the console. And googling is a great way to figure out how to do the modifications you want to your plot.\n\nWhat changes do you expect to see in your plot by adding the following line of code? Discuss with your neighbor and then try it out!\n\nscale_x_continuous(breaks = seq(2000,2016, 2))\n\n\n\n\nAnswer\n## Useful baseline themes are\nggplot(annual_esc_2000s,\n aes(x = Year,\n y = escapement,\n color = Species)) +\n geom_line() +\n geom_point() +\n scale_x_continuous(breaks = seq(2000, 2016, 2)) +\n facet_wrap( ~ SASAP.Region,\n scales = \"free_y\") +\n ylab(\"Escapement\") +\n ggtitle(\"Annual Salmon Escapement by Region\") +\n my_theme +\n theme(axis.text.x = element_text(angle = 45,\n vjust = 0.5))\n\n\n\n\n6.3.3.3 Smarter tick labels using scales\nFixing tick labels in ggplot can be super annoying. The y-axis labels in the plot above don’t look great. We could manually fix them, but it would likely be tedious and error prone.\nThe scales package provides some nice helper functions to easily rescale and relabel your plots. Here, we use scale_y_continuous() from ggplot2, with the argument labels, which is assigned to the function name comma, from the scales package. This will format all of the labels on the y-axis of our plot with comma-formatted numbers.\n\nggplot(annual_esc_2000s,\n aes(x = Year,\n y = escapement,\n color = Species)) +\n geom_line() +\n geom_point() +\n scale_x_continuous(breaks = seq(2000, 2016, 2)) +\n scale_y_continuous(labels = comma) +\n facet_wrap( ~ SASAP.Region,\n scales = \"free_y\") +\n ylab(\"Escapement\") +\n ggtitle(\"Annual Salmon Escapement by Region\") +\n my_theme +\n theme(axis.text.x = element_text(angle = 45,\n vjust = 0.5))\n\n\n\n\nYou can also save all your code into an object in your working environment by assigning a name to the ggplot() code.\n\nannual_region_plot <- ggplot(annual_esc_2000s,\n aes(x = Year,\n y = escapement,\n color = Species)) +\n geom_line() +\n geom_point() +\n scale_x_continuous(breaks = seq(2000, 2016, 2)) +\n scale_y_continuous(labels = comma) +\n facet_wrap( ~ SASAP.Region,\n scales = \"free_y\") +\n ylab(\"Escapement\") +\n xlab(\"\\nYear\") +\n ggtitle(\"Annual Salmon Escapement by Region\") +\n my_theme +\n theme(axis.text.x = element_text(angle = 45,\n vjust = 0.5))\n\nAnd then call your object to see your plot.\n\nannual_region_plot\n\n\n\n\n\n\n6.3.3.4 Reordering things\nggplot() loves putting things in alphabetical order. But more frequent than not, that’s not the order you actually want things to be plotted if you have categorical groups. Let’s find some total years of data by species for Kuskokwim.\n\n## Number Years of data for each salmon species at Kuskokwim\nn_years <- annual_esc %>%\n group_by(SASAP.Region, Species) %>%\n summarize(n = n()) %>%\n filter(SASAP.Region == \"Kuskokwim\")\n\nNow let’s plot this using geom_bar().\n\n## base plot\nggplot(n_years,\n aes(x = Species,\n y = n)) +\n geom_bar(aes(fill = Species),\n stat = \"identity\")\n\n\n\n\nNow, let’s apply some of the customizations we have seen so far and learn some new ones.\n\n## Reordering, flipping coords and other customization\nggplot(n_years,\n aes(\n x = fct_reorder(Species, n),\n y = n,\n fill = Species\n )) +\n geom_bar(stat = \"identity\") +\n coord_flip() +\n theme_minimal() +\n ## another way to customize labels\n labs(x = \"Species\",\n y = \"Number of years of data\",\n title = \"Number of years of escapement data for salmon species in Kuskokwim\") +\n theme(legend.position = \"none\")\n\n\n\n\n\n\n6.3.3.5 Saving plots\nSaving plots using ggplot is easy! The ggsave() function will save either the last plot you created, or any plot that you have saved to a variable. You can specify what output format you want, size, resolution, etc. See ?ggsave() for documentation.\n\nggsave(\"figures/nyears_data_kus.jpg\", width = 8, height = 6, units = \"in\")\n\nWe can also save our facet plot showing annual escapements by region calling the plot’s object.\n\nggsave(annual_region_plot, \"figures/annual_esc_region.png\", width = 12, height = 8, units = \"in\")" + }, + { + "objectID": "session_06.html#interactive-visualization", + "href": "session_06.html#interactive-visualization", + "title": "6  Data Visualization in R", + "section": "6.4 Interactive visualization", + "text": "6.4 Interactive visualization\n\n6.4.1 Tables with DT\nNow that we know how to make great static visualizations, let’s introduce two other packages that allow us to display our data in interactive ways. These packages really shine when used with GitHub Pages, so at the end of this lesson we will publish our figures to the website we created earlier.\nFirst let’s show an interactive table of unique sampling locations using DT. Write a data.frame containing unique sampling locations with no missing values using two new functions from dplyr and tidyr: distinct() and drop_na().\n\nlocations <- escape %>%\n distinct(Location, Latitude, Longitude) %>%\n drop_na()\n\nAnd display it as an interactive table using datatable() from the DT package.\n\ndatatable(locations)\n\n\n\n\n\n\n\n\n6.4.2 Maps with leaflet\nSimilar to ggplot2, you can make a basic leaflet map using just a couple lines of code. Note that unlike ggplot2, the leaflet package uses pipe operators (%>%) and not the additive operator (+).\nThe addTiles() function without arguments will add base tiles to your map from OpenStreetMap. addMarkers() will add a marker at each location specified by the latitude and longitude arguments. Note that the ~ symbol is used here to model the coordinates to the map (similar to facet_wrap() in ggplot).\n\nleaflet(locations) %>%\n addTiles() %>%\n addMarkers(\n lng = ~ Longitude,\n lat = ~ Latitude,\n popup = ~ Location\n )\n\n\n\n\n\n\nYou can also use leaflet to import Web Map Service (WMS) tiles. Here is an example that utilizes the General Bathymetric Map of the Oceans (GEBCO) WMS tiles. In this example, we also demonstrate how to create a more simple circle marker, the look of which is explicitly set using a series of style-related arguments.\n\nleaflet(locations) %>%\n addWMSTiles(\n \"https://www.gebco.net/data_and_products/gebco_web_services/web_map_service/mapserv?request=getmap&service=wms&BBOX=-90,-180,90,360&crs=EPSG:4326&format=image/jpeg&layers=gebco_latest&width=1200&height=600&version=1.3.0\",\n layers = 'GEBCO_LATEST',\n attribution = \"Imagery reproduced from the GEBCO_2022 Grid, WMS 1.3.0 GetMap, www.gebco.net\"\n ) %>%\n addCircleMarkers(\n lng = ~ Longitude,\n lat = ~ Latitude,\n popup = ~ Location,\n radius = 5,\n # set fill properties\n fillColor = \"salmon\",\n fillOpacity = 1,\n # set stroke properties\n stroke = T,\n weight = 0.5,\n color = \"white\",\n opacity = 1\n )\n\n\n\n\n\n\nLeaflet has a ton of functionality that can enable you to create some beautiful, functional maps with relative ease. Here is an example of some we created as part of the State of Alaskan Salmon and People (SASAP) project, created using the same tools we showed you here. This map hopefully gives you an idea of how powerful the combination of R Markdown and GitHub Pages can be." + }, + { + "objectID": "session_06.html#publish-the-data-visualization-lesson-to-your-webpage", + "href": "session_06.html#publish-the-data-visualization-lesson-to-your-webpage", + "title": "6  Data Visualization in R", + "section": "6.5 Publish the Data Visualization lesson to your webpage", + "text": "6.5 Publish the Data Visualization lesson to your webpage\n\n\n\n\n\n\nSteps\n\n\n\n\nSave the Rmd you have been working on for this lesson.\n“Knit” the Rmd. This is a good way to test if everything in your code is working.\nGo to your index.Rmd and the link to the html file with this lesson’s content.\nSave and render index.Rmd to an html.\nUse the Git workflow: Stage > Commit > Pull > Push" + }, + { + "objectID": "session_06.html#ggplot2-resources", + "href": "session_06.html#ggplot2-resources", + "title": "6  Data Visualization in R", + "section": "6.6 ggplot2 Resources", + "text": "6.6 ggplot2 Resources\n\nWhy not to use two axes, and what to use instead: The case against dual axis charts by Lisa Charlotte Rost.\nCustomized Data Visualization in ggplot2 by Allison Horst.\nA ggplot2 tutorial for beautiful plotting in R by Cedric Scherer." + }, + { + "objectID": "session_07.html", + "href": "session_07.html", + "title": "7  Systematic Reviews", + "section": "", + "text": "ADD LINK TO MATERIAL" + }, + { + "objectID": "session_09.html#learning-objectives", + "href": "session_09.html#learning-objectives", + "title": "9  Using sf for Spatia Data & Intro to Making Maps", + "section": "Learning Objectives", + "text": "Learning Objectives\n\nHow to use the sf package to wrangle spatial data\nStatic mapping with ggplot\nAdding basemaps to static maps\nInteractive mapping with leaflet" + }, + { + "objectID": "session_09.html#brief-introduction-to-sf", + "href": "session_09.html#brief-introduction-to-sf", + "title": "9  Using sf for Spatia Data & Intro to Making Maps", + "section": "9.1 Brief introduction to sf", + "text": "9.1 Brief introduction to sf\nFrom the sf vignette:\n\nSimple features or simple feature access refers to a formal standard (ISO 19125-1:2004) that describes how objects in the real world can be represented in computers, with emphasis on the spatial geometry of these objects. It also describes how such objects can be stored in and retrieved from databases, and which geometrical operations should be defined for them.\n\nThe sf package is an R implementation of Simple Features. This package incorporates:\n\na new spatial data class system in R\n\nfunctions for reading and writing spatial data\n\ntools for spatial operations on vectors\n\nMost of the functions in this package starts with prefix st_ which stands for spatial and temporal.\nIn this lesson, our goal is to use a shapefile of Alaska regions and rivers, and data on population in Alaska by community to create a map that looks like this:" + }, + { + "objectID": "session_09.html#about-the-data", + "href": "session_09.html#about-the-data", + "title": "9  Using sf for Spatia Data & Intro to Making Maps", + "section": "9.2 About the data", + "text": "9.2 About the data\nAll of the data used in this tutorial are simplified versions of real datasets available on the KNB Data Repository. We are using simplified datasets to ease the processing burden on all our computers since the original geospatial datasets are high-resolution. These simplified versions of the datasets may contain topological errors.\nThe spatial data we will be using to create the map are:\n\n\n\nData\nOriginal datasets\n\n\n\n\nAlaska regional boundaries\nJared Kibele and Jeanette Clark. 2018. State of Alaska’s Salmon and People Regional Boundaries. Knowledge Network for Biocomplexity. doi:10.5063/F1125QWP.\n\n\nCommunity locations and population\nJeanette Clark, Sharis Ochs, Derek Strong, and National Historic Geographic Information System. 2018. Languages used in Alaskan households, 1990-2015. Knowledge Network for Biocomplexity. doi:10.5063/F11G0JHX.\n\n\nAlaska rivers\nThe rivers shapefile is a simplified version of Jared Kibele and Jeanette Clark. Rivers of Alaska grouped by SASAP region, 2018. Knowledge Network for Biocomplexity. doi:10.5063/F1SJ1HVW.\n\n\n\n\n\n\n\n\n\nSetup\n\n\n\n\nNavigate to this dataset on KNB’s test site and download the zip folder.\nUpload the zip folder to the data folder in the training_{USERNAME} project. You don’t need to unzip the folder ahead of time, uploading will automatically unzip the folder.\nCreate a new R Markdown file.\n\nTitle it “Intro to sf package for Spatial Data and Making Maps”\nSave the file and name it “intro-sf-spatial-data-maps”.\n\nLoad the following libraries at the top of your R Markdown file.\n\n\nlibrary(readr)\nlibrary(sf)\nlibrary(ggplot2)\nlibrary(leaflet)\nlibrary(scales)\nlibrary(ggmap)\nlibrary(dplyr)" + }, + { + "objectID": "session_09.html#exploring-the-data-using-plot-and-st_crs", + "href": "session_09.html#exploring-the-data-using-plot-and-st_crs", + "title": "9  Using sf for Spatia Data & Intro to Making Maps", + "section": "9.3 Exploring the data using plot() and st_crs()", + "text": "9.3 Exploring the data using plot() and st_crs()\nFirst let’s read in the shapefile of regional boundaries in Alaska using read_sf() and then create a basic plot of the data plot().\n\n# read in shapefile using read_sf()\nak_regions <- read_sf(\"data/ak_regions_simp.shp\")\n\n\n# quick plot\nplot(ak_regions)\n\n\n\n\nWe can also examine it’s class using class().\n\nclass(ak_regions)\n\n[1] \"sf\" \"tbl_df\" \"tbl\" \"data.frame\"\n\n\nsf objects usually have two types of classes: sf and data.frame.\nUnlike a typical data.frame, an sf object has spatial metadata (geometry type, dimension, bbox, epsg (SRID), proj4string) and an additional column typically named geometry that contains the spatial data.\nSince our shapefile object has the data.frame class, viewing the contents of the object using the head() function or other exploratory functions shows similar results as if we read in data using read.csv() or read_csv().\n\nhead(ak_regions)\n\nSimple feature collection with 6 features and 3 fields\nGeometry type: MULTIPOLYGON\nDimension: XY\nBounding box: xmin: -179.2296 ymin: 51.15702 xmax: 179.8567 ymax: 71.43957\nGeodetic CRS: WGS 84\n# A tibble: 6 × 4\n region_id region mgmt_area geometry\n <int> <chr> <dbl> <MULTIPOLYGON [°]>\n1 1 Aleutian Islands 3 (((-171.1345 52.44974, -171.1686 52.4174…\n2 2 Arctic 4 (((-139.9552 68.70597, -139.9893 68.7051…\n3 3 Bristol Bay 3 (((-159.8745 58.62778, -159.8654 58.6137…\n4 4 Chignik 3 (((-155.8282 55.84638, -155.8049 55.8655…\n5 5 Copper River 2 (((-143.8874 59.93931, -143.9165 59.9403…\n6 6 Kodiak 3 (((-151.9997 58.83077, -152.0358 58.8271…\n\nglimpse(ak_regions)\n\nRows: 13\nColumns: 4\n$ region_id <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13\n$ region <chr> \"Aleutian Islands\", \"Arctic\", \"Bristol Bay\", \"Chignik\", \"Cop…\n$ mgmt_area <dbl> 3, 4, 3, 3, 2, 3, 4, 4, 2, 4, 2, 1, 4\n$ geometry <MULTIPOLYGON [°]> MULTIPOLYGON (((-171.1345 5..., MULTIPOLYGON (((-139.9552 6.…\n\n\n\n9.3.1 Coordinate Reference System (CRS)\n\n\n\nSource: ESRI\n\n\nEvery sf object needs a coordinate reference system (or crs) defined in order to work with it correctly. A coordinate reference system contains both a datum and a projection. The datum is how you georeference your points (in 3 dimensions!) onto a spheroid. The projection is how these points are mathematically transformed to represent the georeferenced point on a flat piece of paper. All coordinate reference systems require a datum. However, some coordinate reference systems are “unprojected” (also called geographic coordinate systems). Coordinates in latitude/longitude use a geographic (unprojected) coordinate system. One of the most commonly used geographic coordinate systems is WGS 1984.\nESRI has a blog post that explains these concepts in more detail with very helpful diagrams and examples.\nYou can view what crs is set by using the function st_crs().\n\nst_crs(ak_regions)\n\nCoordinate Reference System:\n User input: WGS 84 \n wkt:\nGEOGCRS[\"WGS 84\",\n DATUM[\"World Geodetic System 1984\",\n ELLIPSOID[\"WGS 84\",6378137,298.257223563,\n LENGTHUNIT[\"metre\",1]]],\n PRIMEM[\"Greenwich\",0,\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n CS[ellipsoidal,2],\n AXIS[\"latitude\",north,\n ORDER[1],\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n AXIS[\"longitude\",east,\n ORDER[2],\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n ID[\"EPSG\",4326]]\n\n\nThis is pretty confusing looking. Without getting into the details, that long string says that this data has a geographic coordinate system (WGS84) with no projection. A convenient way to reference crs quickly is by using the EPSG code, a number that represents a standard projection and datum. You can check out a list of (lots!) of EPSG codes here.\nWe will use multiple EPSG codes in this lesson. Here they are, along with their more readable names:\n\n3338: Alaska Albers (projected CRS)\n4326: WGS84 (World Geodetic System 1984), used in GPS (unprojected CRS)\n3857: Pseudo-Mercator, used in Google Maps, OpenStreetMap, Bing, ArcGIS, ESRI (projected CRS)\n\nYou will often need to transform your geospatial data from one coordinate system to another. The st_transform() function does this quickly for us. You may have noticed the maps above looked wonky because of the dateline. We might want to set a different projection for this data so it plots nicer. A good one for Alaska is called the Alaska Albers projection, with an EPSG code of 3338.\n\nak_regions_3338 <- ak_regions %>%\n st_transform(crs = 3338)\n\nst_crs(ak_regions_3338)\n\nCoordinate Reference System:\n User input: EPSG:3338 \n wkt:\nPROJCRS[\"NAD83 / Alaska Albers\",\n BASEGEOGCRS[\"NAD83\",\n DATUM[\"North American Datum 1983\",\n ELLIPSOID[\"GRS 1980\",6378137,298.257222101,\n LENGTHUNIT[\"metre\",1]]],\n PRIMEM[\"Greenwich\",0,\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n ID[\"EPSG\",4269]],\n CONVERSION[\"Alaska Albers (meters)\",\n METHOD[\"Albers Equal Area\",\n ID[\"EPSG\",9822]],\n PARAMETER[\"Latitude of false origin\",50,\n ANGLEUNIT[\"degree\",0.0174532925199433],\n ID[\"EPSG\",8821]],\n PARAMETER[\"Longitude of false origin\",-154,\n ANGLEUNIT[\"degree\",0.0174532925199433],\n ID[\"EPSG\",8822]],\n PARAMETER[\"Latitude of 1st standard parallel\",55,\n ANGLEUNIT[\"degree\",0.0174532925199433],\n ID[\"EPSG\",8823]],\n PARAMETER[\"Latitude of 2nd standard parallel\",65,\n ANGLEUNIT[\"degree\",0.0174532925199433],\n ID[\"EPSG\",8824]],\n PARAMETER[\"Easting at false origin\",0,\n LENGTHUNIT[\"metre\",1],\n ID[\"EPSG\",8826]],\n PARAMETER[\"Northing at false origin\",0,\n LENGTHUNIT[\"metre\",1],\n ID[\"EPSG\",8827]]],\n CS[Cartesian,2],\n AXIS[\"easting (X)\",east,\n ORDER[1],\n LENGTHUNIT[\"metre\",1]],\n AXIS[\"northing (Y)\",north,\n ORDER[2],\n LENGTHUNIT[\"metre\",1]],\n USAGE[\n SCOPE[\"Topographic mapping (small scale).\"],\n AREA[\"United States (USA) - Alaska.\"],\n BBOX[51.3,172.42,71.4,-129.99]],\n ID[\"EPSG\",3338]]\n\n\n\nplot(ak_regions_3338)\n\n\n\n\nMuch better!" + }, + { + "objectID": "session_09.html#sf-the-tidyverse", + "href": "session_09.html#sf-the-tidyverse", + "title": "9  Using sf for Spatia Data & Intro to Making Maps", + "section": "9.4 sf & the Tidyverse", + "text": "9.4 sf & the Tidyverse\nsf objects can be used as a regular data.frame object in many operations. We already saw the results of plot() and head().\nSince sf objects are data.frames, they play nicely with packages in the tidyverse. Here are a couple of simple examples:\n\n9.4.1 select()\n\n# returns the names of all the columns in dataset\ncolnames(ak_regions_3338)\n\n[1] \"region_id\" \"region\" \"mgmt_area\" \"geometry\" \n\n\n\nak_regions_3338 %>%\n select(region)\n\nSimple feature collection with 13 features and 1 field\nGeometry type: MULTIPOLYGON\nDimension: XY\nBounding box: xmin: -2175328 ymin: 405653 xmax: 1579226 ymax: 2383770\nProjected CRS: NAD83 / Alaska Albers\n# A tibble: 13 × 2\n region geometry\n <chr> <MULTIPOLYGON [m]>\n 1 Aleutian Islands (((-1156666 420855.1, -1159837 417990.3, -1161898 41694…\n 2 Arctic (((571289.9 2143072, 569941.5 2142691, 569158.2 2142146…\n 3 Bristol Bay (((-339688.6 973904.9, -339302 972297.3, -339229.2 9710…\n 4 Chignik (((-114381.9 649966.8, -112866.8 652065.8, -108836.8 65…\n 5 Copper River (((561012 1148301, 559393.7 1148169, 557797.7 1148492, …\n 6 Kodiak (((115112.5 983293, 113051.3 982825.9, 110801.3 983211.…\n 7 Kotzebue (((-678815.3 1819519, -677555.2 1820698, -675557.8 1821…\n 8 Kuskokwim (((-1030125 1281198, -1029858 1282333, -1028980 1284032…\n 9 Cook Inlet (((35214.98 1002457, 36660.3 1002038, 36953.11 1001186,…\n10 Norton Sound (((-848357 1636692, -846510 1635203, -840513.7 1632225,…\n11 Prince William Sound (((426007.1 1087250, 426562.5 1088591, 427711.6 1089991…\n12 Southeast (((1287777 744574.1, 1290183 745970.8, 1292940 746262.7…\n13 Yukon (((-375318 1473998, -373723.9 1473487, -373064.8 147393…\n\n\nNote the sticky geometry column! The geometry column will stay with your sf object even if it is not called explicitly.\n\n\n9.4.2 filter()\n\nunique(ak_regions_3338$region)\n\n [1] \"Aleutian Islands\" \"Arctic\" \"Bristol Bay\" \n [4] \"Chignik\" \"Copper River\" \"Kodiak\" \n [7] \"Kotzebue\" \"Kuskokwim\" \"Cook Inlet\" \n[10] \"Norton Sound\" \"Prince William Sound\" \"Southeast\" \n[13] \"Yukon\" \n\n\n\nak_regions_3338 %>%\n filter(region == \"Southeast\")\n\nSimple feature collection with 1 feature and 3 fields\nGeometry type: MULTIPOLYGON\nDimension: XY\nBounding box: xmin: 559475.7 ymin: 722450 xmax: 1579226 ymax: 1410576\nProjected CRS: NAD83 / Alaska Albers\n# A tibble: 1 × 4\n region_id region mgmt_area geometry\n* <int> <chr> <dbl> <MULTIPOLYGON [m]>\n1 12 Southeast 1 (((1287777 744574.1, 1290183 745970.8, 1292940 …" + }, + { + "objectID": "session_09.html#spatial-joins", + "href": "session_09.html#spatial-joins", + "title": "9  Using sf for Spatia Data & Intro to Making Maps", + "section": "9.5 Spatial Joins", + "text": "9.5 Spatial Joins\nYou can also use the sf package to create spatial joins, useful for when you want to utilize two datasets together.\n\n\n\n\n\n\nExercise: How many people live in each of these Alaska regions?\n\n\n\nWe have some population data, but it gives the population by city, not by region. To determine the population per region we will need to:\n\nRead in the population data from a csv and turn it into an sf object\nUse a spatial join (st_join()) to assign each city to a region\nUse group_by() and summarize() to calculate the total population by region\nSave the spatial object you created using write_sf()\n\n\n\n1. Read in alaska_population.csv using read.csv()\n\n# read in population data\npop <- read_csv(\"data/alaska_population.csv\")\n\nTurn pop into a spatial object\nThe st_join() function is a spatial left join. The arguments for both the left and right tables are objects of class sf which means we will first need to turn our population data.frame with latitude and longitude coordinates into an sf object.\nWe can do this easily using the st_as_sf() function, which takes as arguments the coordinates and the crs. The remove = F specification here ensures that when we create our geometry column, we retain our original lat lng columns, which we will need later for plotting. Although it isn’t said anywhere explicitly in the file, let’s assume that the coordinate system used to reference the latitude longitude coordinates is WGS84, which has a crs number of 4326.\n\npop_4326 <- st_as_sf(pop,\n coords = c('lng', 'lat'),\n crs = 4326,\n remove = F)\n\nhead(pop_4326)\n\nSimple feature collection with 6 features and 5 fields\nGeometry type: POINT\nDimension: XY\nBounding box: xmin: -176.6581 ymin: 51.88 xmax: -154.1703 ymax: 62.68889\nGeodetic CRS: WGS 84\n# A tibble: 6 × 6\n year city lat lng population geometry\n <dbl> <chr> <dbl> <dbl> <dbl> <POINT [°]>\n1 2015 Adak 51.9 -177. 122 (-176.6581 51.88)\n2 2015 Akhiok 56.9 -154. 84 (-154.1703 56.94556)\n3 2015 Akiachak 60.9 -161. 562 (-161.4314 60.90944)\n4 2015 Akiak 60.9 -161. 399 (-161.2139 60.91222)\n5 2015 Akutan 54.1 -166. 899 (-165.7731 54.13556)\n6 2015 Alakanuk 62.7 -165. 777 (-164.6153 62.68889)\n\n\n2. Join population data with Alaska regions data using st_join()\nNow we can do our spatial join! You can specify what geometry function the join uses (st_intersects, st_within, st_crosses, st_is_within_distance…) in the join argument. The geometry function you use will depend on what kind of operation you want to do, and the geometries of your shapefiles.\nIn this case, we want to find what region each city falls within, so we will use st_within.\n\npop_joined <- st_join(pop_4326, ak_regions_3338, join = st_within)\n\nThis gives an error!\nError: st_crs(x) == st_crs(y) is not TRUE\nTurns out, this won’t work right now because our coordinate reference systems are not the same. Luckily, this is easily resolved using st_transform(), and projecting our population object into Alaska Albers.\n\npop_3338 <- st_transform(pop_4326, crs = 3338)\n\n\npop_joined <- st_join(pop_3338, ak_regions_3338, join = st_within)\n\nhead(pop_joined)\n\nSimple feature collection with 6 features and 8 fields\nGeometry type: POINT\nDimension: XY\nBounding box: xmin: -1537925 ymin: 472626.9 xmax: -10340.71 ymax: 1456223\nProjected CRS: NAD83 / Alaska Albers\n# A tibble: 6 × 9\n year city lat lng population geometry region_id region \n <dbl> <chr> <dbl> <dbl> <dbl> <POINT [m]> <int> <chr> \n1 2015 Adak 51.9 -177. 122 (-1537925 472626.9) 1 Aleutian I…\n2 2015 Akhiok 56.9 -154. 84 (-10340.71 770998.4) 6 Kodiak \n3 2015 Akiac… 60.9 -161. 562 (-400885.5 1236460) 8 Kuskokwim \n4 2015 Akiak 60.9 -161. 399 (-389165.7 1235475) 8 Kuskokwim \n5 2015 Akutan 54.1 -166. 899 (-766425.7 526057.8) 1 Aleutian I…\n6 2015 Alaka… 62.7 -165. 777 (-539724.9 1456223) 13 Yukon \n# ℹ 1 more variable: mgmt_area <dbl>\n\n\n\n\n\n\n\n\nExploring types of joins\n\n\n\nThere are many different types of joins you can do with geospatial data. Examine the help page for these joins (?st_within() will get you there). What other joins types might be appropriate for examining the relationship between points and polygyons? What about two sets of polygons?\n\n\n3. Calculate the total population by region using group_by() and summarize()\nNext we compute the total population for each region. In this case, we want to do a group_by() and summarise() as this were a regular data.frame. Otherwise all of our point geometries would be included in the aggregation, which is not what we want. Our goal is just to get the total population by region. We remove the sticky geometry using as.data.frame(), on the advice of the sf::tidyverse help page.\n\npop_region <- pop_joined %>%\n as.data.frame() %>%\n group_by(region) %>%\n summarise(total_pop = sum(population))\n\nhead(pop_region)\n\n# A tibble: 6 × 2\n region total_pop\n <chr> <dbl>\n1 Aleutian Islands 8840\n2 Arctic 8419\n3 Bristol Bay 6947\n4 Chignik 311\n5 Cook Inlet 408254\n6 Copper River 2294\n\n\nAnd use a regular left_join() to get the information back to the Alaska region shapefile. Note that we need this step in order to regain our region geometries so that we can make some maps.\n\npop_region_3338 <- left_join(ak_regions_3338, pop_region, by = \"region\")\n\n# plot to check\nplot(pop_region_3338[\"total_pop\"])\n\n\n\n\nSo far, we have learned how to use sf and dplyr to use a spatial join on two datasets and calculate a summary metric from the result of that join.\n\n\n\n\n\n\nsf and tidyverse best practices\n\n\n\nThe group_by() and summarize() functions can also be used on sf objects to summarize within a dataset and combine geometries. Many of the tidyverse functions have methods specific for sf objects, some of which have additional arguments that wouldn’t be relevant to the data.frame methods. You can run ?sf::tidyverse to get documentation on the tidyverse sf methods.\n\n\nSay we want to calculate the population by Alaska management area, as opposed to region.\n\npop_mgmt_338 <- pop_region_3338 %>%\n group_by(mgmt_area) %>%\n summarize(total_pop = sum(total_pop))\n\nplot(pop_mgmt_338[\"total_pop\"])\n\n\n\n\nNotice that the region geometries were combined into a single polygon for each management area.\nIf we don’t want to combine geometries, we can specify do_union = F as an argument.\n\npop_mgmt_3338 <- pop_region_3338 %>%\n group_by(mgmt_area) %>%\n summarize(total_pop = sum(total_pop), do_union = F)\n\nplot(pop_mgmt_3338[\"total_pop\"])\n\n\n\n\n4. Save the spatial object to a new file using write_sf()\nSave the spatial object to disk using write_sf() and specifying the filename. Writing your file with the extension .shp will assume an ESRI driver driver, but there are many other format options available.\n\nwrite_sf(pop_region_3338, \"data/ak_regions_population.shp\")\n\n\n9.5.1 Visualize with ggplot\nggplot2 now has integrated functionality to plot sf objects using geom_sf().\nWe can plot sf objects just like regular data.frames using geom_sf.\n\nggplot(pop_region_3338) +\n geom_sf(aes(fill = total_pop)) +\n labs(fill = \"Total Population\") +\n scale_fill_continuous(low = \"khaki\",\n high = \"firebrick\",\n labels = comma) +\n theme_bw()\n\n\n\n\nWe can also plot multiple shapefiles in the same plot. Say if we want to visualize rivers in Alaska, in addition to the location of communities, since many communities in Alaska are on rivers. We can read in a rivers shapefile, doublecheck the crs to make sure it is what we need, and then plot all three shapefiles - the regional population (polygons), the locations of cities (points), and the rivers (linestrings).\n\n\nCoordinate Reference System:\n User input: Albers \n wkt:\nPROJCRS[\"Albers\",\n BASEGEOGCRS[\"GCS_GRS 1980(IUGG, 1980)\",\n DATUM[\"D_unknown\",\n ELLIPSOID[\"GRS80\",6378137,298.257222101,\n LENGTHUNIT[\"metre\",1,\n ID[\"EPSG\",9001]]]],\n PRIMEM[\"Greenwich\",0,\n ANGLEUNIT[\"Degree\",0.0174532925199433]]],\n CONVERSION[\"unnamed\",\n METHOD[\"Albers Equal Area\",\n ID[\"EPSG\",9822]],\n PARAMETER[\"Latitude of false origin\",50,\n ANGLEUNIT[\"Degree\",0.0174532925199433],\n ID[\"EPSG\",8821]],\n PARAMETER[\"Longitude of false origin\",-154,\n ANGLEUNIT[\"Degree\",0.0174532925199433],\n ID[\"EPSG\",8822]],\n PARAMETER[\"Latitude of 1st standard parallel\",55,\n ANGLEUNIT[\"Degree\",0.0174532925199433],\n ID[\"EPSG\",8823]],\n PARAMETER[\"Latitude of 2nd standard parallel\",65,\n ANGLEUNIT[\"Degree\",0.0174532925199433],\n ID[\"EPSG\",8824]],\n PARAMETER[\"Easting at false origin\",0,\n LENGTHUNIT[\"metre\",1],\n ID[\"EPSG\",8826]],\n PARAMETER[\"Northing at false origin\",0,\n LENGTHUNIT[\"metre\",1],\n ID[\"EPSG\",8827]]],\n CS[Cartesian,2],\n AXIS[\"(E)\",east,\n ORDER[1],\n LENGTHUNIT[\"metre\",1,\n ID[\"EPSG\",9001]]],\n AXIS[\"(N)\",north,\n ORDER[2],\n LENGTHUNIT[\"metre\",1,\n ID[\"EPSG\",9001]]]]\n\n\n\nrivers_3338 <- read_sf(\"data/ak_rivers_simp.shp\")\nst_crs(rivers_3338)\n\nNote that although no EPSG code is set explicitly, with some sluething we can determine that this is EPSG:3338. This site is helpful for looking up EPSG codes.\n\nggplot() +\n geom_sf(data = pop_region_3338, aes(fill = total_pop)) +\n geom_sf(data = pop_3338, size = 0.5) +\n geom_sf(data = rivers_3338,\n aes(linewidth = StrOrder)) +\n scale_linewidth(range = c(0.05, 0.5), guide = \"none\") +\n labs(title = \"Total Population by Alaska Region\",\n fill = \"Total Population\") +\n scale_fill_continuous(low = \"khaki\",\n high = \"firebrick\",\n labels = comma) +\n theme_bw()" + }, + { + "objectID": "session_09.html#incorporate-base-maps-into-static-maps-using-ggmap", + "href": "session_09.html#incorporate-base-maps-into-static-maps-using-ggmap", + "title": "9  Using sf for Spatia Data & Intro to Making Maps", + "section": "9.6 Incorporate base maps into static maps using ggmap", + "text": "9.6 Incorporate base maps into static maps using ggmap\nThe ggmap package has some functions that can render base maps (as raster objects) from open tile servers like Google Maps, Stamen, OpenStreetMap, and others.\nWe’ll need to transform our shapefile with population data by community to EPSG:3857 which is the crs used for rendering maps in Google Maps, Stamen, and OpenStreetMap, among others.\n\npop_3857 <- pop_3338 %>%\n st_transform(crs = 3857)\n\nNext, let’s grab a base map from the Stamen map tile server covering the region of interest. First we include a function that transforms the bounding box (which starts in EPSG:4326) to also be in the EPSG:3857 CRS, which is the projection that the map raster is returned in from Stamen. This is an issue with ggmap described in more detail here\n\n# Define a function to fix the bbox to be in EPSG:3857\n# See https://github.com/dkahle/ggmap/issues/160#issuecomment-397055208\nggmap_bbox_to_3857 <- function(map) {\n if (!inherits(map, \"ggmap\"))\n stop(\"map must be a ggmap object\")\n # Extract the bounding box (in lat/lon) from the ggmap to a numeric vector,\n # and set the names to what sf::st_bbox expects:\n map_bbox <- setNames(unlist(attr(map, \"bb\")),\n c(\"ymin\", \"xmin\", \"ymax\", \"xmax\"))\n \n # Coonvert the bbox to an sf polygon, transform it to 3857,\n # and convert back to a bbox (convoluted, but it works)\n bbox_3857 <-\n st_bbox(st_transform(st_as_sfc(st_bbox(map_bbox, crs = 4326)), 3857))\n \n # Overwrite the bbox of the ggmap object with the transformed coordinates\n attr(map, \"bb\")$ll.lat <- bbox_3857[\"ymin\"]\n attr(map, \"bb\")$ll.lon <- bbox_3857[\"xmin\"]\n attr(map, \"bb\")$ur.lat <- bbox_3857[\"ymax\"]\n attr(map, \"bb\")$ur.lon <- bbox_3857[\"xmax\"]\n map\n}\n\nNext, we define the bounding box of interest, and use get_stamenmap() to get the basemap. Then we run our function defined above on the result of the get_stamenmap() call.\n\nbbox <- c(-170, 52,-130, 64) # this is roughly southern Alaska\nak_map <- get_stamenmap(bbox, zoom = 4) # get base map\nak_map_3857 <- ggmap_bbox_to_3857(ak_map) # fix the bbox to be in EPSG:3857\n\nFinally, plot both the base raster map with the population data overlayed, which is easy now that everything is in the same projection (3857):\n\nggmap(ak_map_3857) +\n geom_sf(data = pop_3857,\n aes(color = population),\n inherit.aes = F) +\n scale_color_continuous(low = \"khaki\",\n high = \"firebrick\",\n labels = comma)" + }, + { + "objectID": "session_09.html#visualize-sf-objects-with-leaflet", + "href": "session_09.html#visualize-sf-objects-with-leaflet", + "title": "9  Using sf for Spatia Data & Intro to Making Maps", + "section": "9.7 Visualize sf objects with leaflet", + "text": "9.7 Visualize sf objects with leaflet\nWe can also make an interactive map from our data above using leaflet.\nleaflet (unlike ggplot) will project data for you. The catch is that you have to give it both a projection (like Alaska Albers), and that your shapefile must use a geographic coordinate system. This means that we need to use our shapefile with the 4326 EPSG code. Remember you can always check what crs you have set using st_crs.\nHere we define a leaflet projection for Alaska Albers, and save it as a variable to use later.\n\nepsg3338 <- leaflet::leafletCRS(\n crsClass = \"L.Proj.CRS\",\n code = \"EPSG:3338\",\n proj4def = \"+proj=aea +lat_1=55 +lat_2=65 +lat_0=50 +lon_0=-154 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs\",\n resolutions = 2 ^ (16:7)\n)\n\nYou might notice that this looks familiar! The syntax is a bit different, but most of this information is also contained within the crs of our shapefile:\n\nst_crs(pop_region_3338)\n\nCoordinate Reference System:\n User input: EPSG:3338 \n wkt:\nPROJCRS[\"NAD83 / Alaska Albers\",\n BASEGEOGCRS[\"NAD83\",\n DATUM[\"North American Datum 1983\",\n ELLIPSOID[\"GRS 1980\",6378137,298.257222101,\n LENGTHUNIT[\"metre\",1]]],\n PRIMEM[\"Greenwich\",0,\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n ID[\"EPSG\",4269]],\n CONVERSION[\"Alaska Albers (meters)\",\n METHOD[\"Albers Equal Area\",\n ID[\"EPSG\",9822]],\n PARAMETER[\"Latitude of false origin\",50,\n ANGLEUNIT[\"degree\",0.0174532925199433],\n ID[\"EPSG\",8821]],\n PARAMETER[\"Longitude of false origin\",-154,\n ANGLEUNIT[\"degree\",0.0174532925199433],\n ID[\"EPSG\",8822]],\n PARAMETER[\"Latitude of 1st standard parallel\",55,\n ANGLEUNIT[\"degree\",0.0174532925199433],\n ID[\"EPSG\",8823]],\n PARAMETER[\"Latitude of 2nd standard parallel\",65,\n ANGLEUNIT[\"degree\",0.0174532925199433],\n ID[\"EPSG\",8824]],\n PARAMETER[\"Easting at false origin\",0,\n LENGTHUNIT[\"metre\",1],\n ID[\"EPSG\",8826]],\n PARAMETER[\"Northing at false origin\",0,\n LENGTHUNIT[\"metre\",1],\n ID[\"EPSG\",8827]]],\n CS[Cartesian,2],\n AXIS[\"easting (X)\",east,\n ORDER[1],\n LENGTHUNIT[\"metre\",1]],\n AXIS[\"northing (Y)\",north,\n ORDER[2],\n LENGTHUNIT[\"metre\",1]],\n USAGE[\n SCOPE[\"Topographic mapping (small scale).\"],\n AREA[\"United States (USA) - Alaska.\"],\n BBOX[51.3,172.42,71.4,-129.99]],\n ID[\"EPSG\",3338]]\n\n\nSince leaflet requires that we use an unprojected coordinate system, let’s use st_transform() yet again to get back to WGS84.\n\npop_region_4326 <- pop_region_3338 %>% st_transform(crs = 4326)\n\n\nm <- leaflet(options = leafletOptions(crs = epsg3338)) %>%\n addPolygons(data = pop_region_4326,\n fillColor = \"gray\",\n weight = 1)\n\nm\n\n\n\n\n\nWe can add labels, legends, and a color scale.\n\npal <- colorNumeric(palette = \"Reds\", domain = pop_region_4326$total_pop)\n\nm <- leaflet(options = leafletOptions(crs = epsg3338)) %>%\n addPolygons(\n data = pop_region_4326,\n fillColor = ~ pal(total_pop),\n weight = 1,\n color = \"black\",\n fillOpacity = 1,\n label = ~ region\n ) %>%\n addLegend(\n position = \"bottomleft\",\n pal = pal,\n values = range(pop_region_4326$total_pop),\n title = \"Total Population\"\n )\n\nm\n\n\n\n\n\nWe can also add the individual communities, with popup labels showing their population, on top of that!\n\npal <- colorNumeric(palette = \"Reds\", domain = pop_region_4326$total_pop)\n\nm <- leaflet(options = leafletOptions(crs = epsg3338)) %>%\n addPolygons(\n data = pop_region_4326,\n fillColor = ~ pal(total_pop),\n weight = 1,\n color = \"black\",\n fillOpacity = 1\n ) %>%\n addCircleMarkers(\n data = pop_4326,\n lat = ~ lat,\n lng = ~ lng,\n radius = ~ log(population / 500),\n # arbitrary scaling\n fillColor = \"gray\",\n fillOpacity = 1,\n weight = 0.25,\n color = \"black\",\n label = ~ paste0(pop_4326$city, \", population \", comma(pop_4326$population))\n ) %>%\n addLegend(\n position = \"bottomleft\",\n pal = pal,\n values = range(pop_region_4326$total_pop),\n title = \"Total Population\"\n )\n\nm" + }, + { + "objectID": "session_09.html#more-spatial-resources", + "href": "session_09.html#more-spatial-resources", + "title": "9  Using sf for Spatia Data & Intro to Making Maps", + "section": "9.8 More Spatial Resources", + "text": "9.8 More Spatial Resources\nThere is a lot more functionality to sf including the ability to intersect polygons, calculate distance, create a buffer, and more. Here are some more great resources and tutorials for a deeper dive into this great package:\n\nRaster analysis in R\n\nSpatial analysis in R with the sf package\n\nIntro to Spatial Analysis\n\nsf github repo\n\nTidy spatial data in R: using dplyr, tidyr, and ggplot2 with sf\n\nmapping-fall-foliage-with-sf" + }, + { + "objectID": "session_10.html", + "href": "session_10.html", + "title": "10  Introduction to Meta-Analysis", + "section": "", + "text": "ADD LINK TO MATERIALS" + }, + { + "objectID": "session_11.html#unstructured-text", + "href": "session_11.html#unstructured-text", + "title": "11  Working with Text Data in R", + "section": "11.1 Unstructured Text", + "text": "11.1 Unstructured Text\nThe above example showed how to analyze text that was contained within a tabular format (a csv file). There are many other text formats that you might want to analyze, however. This might include pdf documents, websites, word documents, etc. Here, we’ll look at how to read in the text from a PDF document into an analysis pipeline like above.\nBefore we begin, it is important to understand that not all PDF documents can be processed this way. PDF files can store information in many ways, including both images and text. Some PDF documents, particularly older ones, or scanned documents, are images of text and the bytes making up the document do not contain a ‘readable’ version of the text in the image, it is an image not unlike one you would take with a camera. Other PDF documents will contain the text as character strings, along with the information on how to render it on the page (such as position and font). The analysis that follows will only work on PDF files that fit the second description of the format. If the PDF document you are trying to analyze is more like the first, you would need to first use a technique called Optical Character Recognition (OCR) to interpret the text in the image and store it in a parsable way. Since this document can be parsed, we’ll proceed without doing OCR.\nFirst we’ll load another library, pdftools, which will read in our PDF, and the stringr library, which helps manipulate character strings.\n\nlibrary(pdftools)\nlibrary(stringr)\n\nNext, navigate to the dataset Elizabeth Rink and Gitte Adler Reimer. 2022. Population Dynamics in Greenland: A Multi-component Mixed-methods Study of Pregnancy Dynamics in Greenland (2014-2022). Arctic Data Center. doi:10.18739/A21Z41V1R.. Right click the download button next to the top PDF data file called ‘Translation_of_FG_8_Ilulissat_170410_0077.pdf’.\nFirst we create a variable with a path to a location where we want to save the file.\n\npath <- \"data/Translation_of_FG_8_Ilulissat_170410_0077.pdf\"\n\nThen use download.file to download it and save it to that path.\n\ndownload.file(\"https://arcticdata.io/metacat/d1/mn/v2/object/urn%3Auuid%3A34999083-2fa1-4222-ab27-53204327e8fc\", path)\n\nThe pdf_text function extracts the text from the PDF file, returning a vector of character strings with a length equal to the number of pages in the file. So, our return value is loaded into R, but maybe not that useful yet because it is just a bunch of really long strings.\n\ntxt <- pdf_text(path)\n\nclass(txt)\n\n[1] \"character\"\n\n\nLuckily, there is a function that will turn the pdf text data we just read in to a form that is compatible with the rest of the tidytext tools. The tibble::enframe function, converts the list into a data.frame. We then change one column name to describe what the column actually is (page number).\n\ntxt_clean <- txt %>%\n enframe() %>% \n rename(page = name) \n\nWe can do the same analysis as above, unnesting the tokens and removing stop words to get the most frequent words:\n\npdf_summary <- txt_clean %>% \n unnest_tokens(output = word, input = value) %>%\n anti_join(stop_words) %>% \n count(word) %>% \n arrange(-n) %>% \n slice_head(n = 10)\n\nJoining with `by = join_by(word)`\n\n\n\n\n\n\n\n\n\nIf we look at the result, and then back at the original document, it is clear that there is more work needed to get the data to an analyzable state. The header and footer of each page of the PDF were included in the text we analyzed, and since they are repeated every page (and aren’t really the subject of our inquiry anyway), should be removed from the text after we read it into R but before we try to calculate the most used words. It might also be beneficial to try and separate out the questions from responses, if we wanted to analyze just the responses or just the questions.\nTo help us clean things up, first let’s split our value column currently containing full pages of text by where there are double newlines (\\n\\n). You can see in the original PDF how this demarcates the responses, which contain single newlines within each paragraph, and two new lines (an empty line) between paragraphs. You can see an example of this within the text we have read in by examining just the first 500 characters of the first page of data.\n\nsubstr(txt_clean$value[1], 1,500)\n\n[1] \" Population Dynamics in Greenland\\n Focus Group Meetings\\n\\nDate of the focus group meeting: Ilulissat April 10th, 2017\\nName and title of the Researchers: Q3: Dr. Elizabeth Rink & Q1: Dr. Gitte Adler\\nReimer\\nName of the facilitator: Q2: Majbritt Didriksen Raal\\nRecord No.: 170410_0077\\n\\nFG # 8\\n\\nQ2: Ilulissat the April 10th, 2017, we are going to talk to the Professional Group.\\n\\nQ1: Welcome, we are working on the final part of t\"\n\n\nTo split our character vectors, we will use the str_split function. It splits a character vector according to a separator, and stores the values in a list. To show more clearly, let’s look at a dummy example. We can split a string of comma separated numbers into a list with each individual number.\n\nx <- \"1,2,3,4,5\"\nstr_split(x, \",\")\n\n[[1]]\n[1] \"1\" \"2\" \"3\" \"4\" \"5\"\n\n\nIn the real dataset, we’ll use str_split and mutate, which will create a list of values within each row of the value column. So each cell in the value column contains a list of values like the result of the example above. We can “flatten” this data so that each cell only has one value by using the unnest function, which takes as arguments the columns to flatten. Let’s take the example above, and make it a little more like our real data.\nFirst turn the original dummy vector into a data frame, and do our split as before, this time using mutate.\n\nx_df <- data.frame(x = x) %>% \n mutate(x = str_split(x, \",\"))\nx_df\n\n x\n1 1, 2, 3, 4, 5\n\n\nThen you can run the unnest on the column of split values we just created.\n\nx_df_flat <- x_df %>% \n tidyr::unnest(cols = x)\n\nx_df_flat\n\n# A tibble: 5 × 1\n x \n <chr>\n1 1 \n2 2 \n3 3 \n4 4 \n5 5 \n\n\nNow that we know how this works, let’s do it on our dataset with the double newline character as the separator.\n\ntxt_clean <- txt_clean %>%\n mutate(value = str_split(value, \"\\n\\n\")) %>% \n tidyr::unnest(cols = value)\n\n\nDT::datatable(txt_clean, rownames = F)\n\n\n\n\n\n\nYou can see that our questions and answers are now easily visible because they all start with wither Q or A. The other lines are blank lines or header/footer lines from the document. So, let’s extract the first few characters of each line into a new column using substr, with the goal that we’ll run a filter for rows that start with Q or A, thus discarding all the other rows.\nFirst, we extract the first 4 characters of each row and using mutate create a new column with those values called id.\n\ntxt_clean <- txt_clean %>% \n mutate(id = substr(value, 1, 4))\n\nLet’s have a look at the unique values there:\n\nunique(txt_clean$id)\n\n [1] \" \" \"Date\" \"FG #\" \"Q2: \" \"Q1: \" \"A1: \" \"PDG \" \"A2: \" \"\\nQ2:\"\n[10] \"\\nQ2.\" \"\\nPDG\" \"\" \"A1 \" \"Q3: \" \n\n\nSo unfortunately some of the text is a tiny bit garbled, there are newlines before at least some Q and A ids. We can use mutate again with str_replace to replace those \\n with a blank value, which will remove them.\n\ntxt_clean <- txt_clean %>% \n mutate(id = substr(value, 1, 4)) %>% \n mutate(id = str_replace(id, \"\\n\", \"\"))\n\n\nunique(txt_clean$id)\n\n [1] \" \" \"Date\" \"FG #\" \"Q2: \" \"Q1: \" \"A1: \" \"PDG \" \"A2: \" \"Q2:\" \"Q2.\" \n[11] \"PDG\" \"\" \"A1 \" \"Q3: \"\n\n\nNow we will use substr again to get the first two characters of each id.\n\ntxt_clean <- txt_clean %>% \n mutate(id = substr(value, 1, 4)) %>% \n mutate(id = str_replace(id, \"\\n\", \"\")) %>% \n mutate(id = substr(id, 1, 2))\n\n\nunique(txt_clean$id)\n\n [1] \" \" \"Da\" \"FG\" \"Q2\" \"Q1\" \"A1\" \"PD\" \"A2\" \"\" \"Q3\"\n\n\nFinally, we can run the filter. Here, we filter for id values that start with either a Q or an A using the grepl function and a regular expression. We won’t go much into regular expression details, but there is a chapter in the appendix for more about how they work.\nHere is an example of grepl in action. It returns a true or false for whether the value of x starts with (signified by ^) a Q or A (signified by QA in square brackets).\n\nx <- c(\"Q3\", \"F1\", \"AAA\", \"FA\")\ngrepl(\"^[QA]\", x)\n\n[1] TRUE FALSE TRUE FALSE\n\n\nSo let’s run that within a filter which will return only rows where the grepl would return TRUE.\n\ntxt_clean <- txt_clean %>% \n mutate(id = substr(value, 1, 4)) %>% \n mutate(id = str_replace(id, \"\\n\", \"\")) %>% \n mutate(id = substr(id, 1, 2)) %>% \n filter(grepl(\"^[QA]\", id))\n\n\n\n\n\n\n\n\nFinally, as our last cleaning step we replace all instances of the start of a string that contains a Q or A, followed by a digit and a colon, with an empty string (removing them from the beginning of the line.\n\ntxt_clean <- txt_clean %>% \n mutate(id = substr(value, 1, 4)) %>% \n mutate(id = str_replace(id, \"\\n\", \"\")) %>% \n mutate(id = substr(id, 1, 2)) %>% \n filter(grepl(\"^[QA]\", id)) %>% \n mutate(value = str_replace_all(value, \"[QA][0-9]\\\\:\", \"\"))\n\n\n\n\n\n\n\n\nFinally, we can try the same analysis again as above to look for the most commonly used words.\n\npdf_summary <- txt_clean %>% \n unnest_tokens(output = word, input = value) %>%\n anti_join(stop_words) %>% \n count(word) %>% \n arrange(-n) %>% \n slice_head(n = 10)\n\nJoining with `by = join_by(word)`" + }, + { + "objectID": "session_11.html#sentiment-analysis", + "href": "session_11.html#sentiment-analysis", + "title": "11  Working with Text Data in R", + "section": "11.2 Sentiment Analysis", + "text": "11.2 Sentiment Analysis\nIn sentiment analysis, tokens (in this case our single words) are evaluated against a dictionary of words where a sentiment is assigned to the word. There are many different sentiment lexicons, some with single words, some with more than one word, and some that are aimed at particular disciplines. When embarking on a sentiment analysis project, choosing your lexicon is one that should be done with care. Sentiment analysis can also be done using machine learning algorithms.\nWith that in mind, we will next do a very simple sentiment analysis on our Q3 and Q4 answers using the bing lexicon from Bing Liu and collaborators, which ships with the tidytext package.\nFirst we will use the get_sentiments function to load the lexicon.\n\nbing <- get_sentiments(\"bing\")\n\nNext we do an inner join to return the words from question 3 that are contained within the lexicon.\n\nq3_sent <- inner_join(q3, bing, by = \"word\")\n\n\n\n\n\n\n\n\nThere are a variety of directions you could go from here, analysis wise, such as calculating an overall sentiment index for that question, plotting sentiment against some other variable, or, making a fun word cloud like below! Here we bring in reshape2::acast to create a sentiment matrix for each word, and pass that into wordcloud::comparison.cloud to look at a wordcloud that indicates the frequency and sentiment of the words in our responses.\n\nq3_sent %>% \n count(word, sentiment, sort = TRUE) %>%\n acast(word ~ sentiment, value.var = \"n\", fill = 0) %>%\n comparison.cloud(colors = c(\"gray20\", \"gray80\"),\n max.words = 100, title.size = 2)\n\n\n\n\nLet’s look at the question 4 word cloud:\n\nq4 %>%\n inner_join(bing, by = \"word\") %>% \n count(word, sentiment, sort = TRUE) %>%\n acast(word ~ sentiment, value.var = \"n\", fill = 0) %>%\n comparison.cloud(colors = c(\"gray20\", \"gray80\"),\n max.words = 100, title.size = 2)" + }, + { + "objectID": "session_11.html#summary", + "href": "session_11.html#summary", + "title": "11  Working with Text Data in R", + "section": "11.3 Summary", + "text": "11.3 Summary\nIn this lesson, we learned:\n\nhow to analyze structured text data from a survey using stop words and sentiment analysis\nhow to give structure to unstructured text data from a PDF to do some analysis using stop words and times words are used" + }, + { + "objectID": "session_12.html#learning-objectives", + "href": "session_12.html#learning-objectives", + "title": "12  Working with US Census Data", + "section": "Learning Objectives", + "text": "Learning Objectives" + }, + { + "objectID": "session_12.html#overview", + "href": "session_12.html#overview", + "title": "12  Working with US Census Data", + "section": "12.1 Overview", + "text": "12.1 Overview\n(Chapter 1 - 5 min) - General view of US Census Data" + }, + { + "objectID": "session_12.html#introduction-to-tidycensus", + "href": "session_12.html#introduction-to-tidycensus", + "title": "12  Working with US Census Data", + "section": "12.2 Introduction to tidycensus", + "text": "12.2 Introduction to tidycensus\n(Chapter 2 - 25-30 min)\n\nBasic data requests\nFundamentals of data package and the options it offers" + }, + { + "objectID": "session_12.html#getting-census-data-ready-for-analysis", + "href": "session_12.html#getting-census-data-ready-for-analysis", + "title": "12  Working with US Census Data", + "section": "12.3 Getting Census Data ready for analysis", + "text": "12.3 Getting Census Data ready for analysis\n(Chapter 3 - 20-25 min)\n\nData wranglw again? Yes!\nHandling errors in data" + }, + { + "objectID": "session_12.html#visualizing-censis-data-with-ggplot2", + "href": "session_12.html#visualizing-censis-data-with-ggplot2", + "title": "12  Working with US Census Data", + "section": "12.4 Visualizing Censis Data with ggplot2", + "text": "12.4 Visualizing Censis Data with ggplot2\n(Chapter 4 - 20 min)" + }, + { + "objectID": "session_12.html#maps-and-census-data", + "href": "session_12.html#maps-and-census-data", + "title": "12  Working with US Census Data", + "section": "12.5 Maps and Census Data", + "text": "12.5 Maps and Census Data\n( Chapter 5 and 6 - 10 min?)" + }, + { + "objectID": "session_13.html", + "href": "session_13.html", + "title": "13  Reproducible Surveys", + "section": "", + "text": "13.0.1 Learning Objectives\n\nOverview of survey tools\nGenerating a reproducible survey report with Qualtrics\n\n\n\n13.0.2 Introduction\nSurveys and questionnaires are commonly used research methods within social science and other fields. For example, understanding regional and national population demographics, income, and education as part of the National Census activity, assessing audience perspectives on specific topics of research interest (e.g. the work by Tenopir and colleagues on Data Sharing by Scientists), evaluation of learning deliverables and outcomes, and consumer feedback on new and upcoming products. These are distinct from the use of the term survey within natural sciences, which might include geographical surveys (“the making of measurement in the field from which maps are drawn”), ecological surveys (“the process whereby a proposed development site is assess to establish any environmental impact the development may have”) or biodiversity surveys (“provide detailed information about biodiversity and community structure”) among others.\nAlthough surveys can be conducted on paper or verbally, here we focus on surveys done via software tools. Needs will vary according to the nature of the research being undertaken. However, there is fundamental functionality that survey software should provide including:\n\nThe ability to create and customize questions\nThe ability to include different types of questions\nThe ability to distribute the survey and manage response collection\nThe ability to collect, summarize, and (securely) store response data\n\nMore advanced features can include:\n\nVisual design and templates - custom design might include institutional branding or aesthetic elements. Templates allow you to save these designs and apply to other surveys\nQuestion piping - piping inserts answers from previous questions into upcoming questions and can personalize the survey experience for users\nSurvey logic - with question logic and skip logic you can control the inclusion / exclusion of questions based on previous responses\nRandomization - the ability to randomize the presentation of questions within (blocks of) the survey\nBranching - this allows for different users to take different paths through the survey. Similar to question logic but at a bigger scale\nLanguage support - automated translation or multi-language presentation support\nShared administration - enables collaboration on the survey and response analysis\nSurvey export - ability to download (export) the survey instrument\nReports - survey response visualization and reporting tools\nInstitutional IRB approved - institutional IRB policy may require certain software be used for research purposes\n\nCommonly used survey software within academic (vs market) research include Qualtrics, Survey Monkey and Google Forms. Both qualtrics and survey monkey are licensed (with limited functionality available at no cost) and google forms is free.\n\n\n\n13.0.3 Building workflows using Qualtrics\nIn this lesson we will use the qualtRics package to reproducible access some survey results set up for this course.\n\n13.0.3.1 Survey Instrument\nThe survey is very short, only four questions. The first question is on it’s own page and is a consent question, after a couple of short paragraphs describing what the survey is, it’s purpose, how long it will take to complete, and who is conducting it. This type of information is required if the survey is governed by an IRB, and the content will depend on the type of research being conducted. In this case, this survey is not for research purposes, and thus is not governed by IRB, but we still include this information as it conforms to the Belmont Principles. The Belmont Principles identify the basic ethical principles that should underlie research involving human subjects.\n\nThe three main questions of the survey have three types of responses: a multiple choice answer, a multiple choice answer which also includes an “other” write in option, and a free text answer. We’ll use the results of this survey, which was sent out to NCEAS staff to fill out, to learn about how to create a reproducible survey report.\n\nFirst, open a new RMarkdown document and add a chunk to load the libraries we’ll need for this lesson:\n\nlibrary(qualtRics)\nlibrary(tidyr)\nlibrary(knitr)\nlibrary(ggplot2)\nlibrary(kableExtra)\nlibrary(dplyr)\n\nNext, we need to set the API credentials. This function modifies the .Renviron file to set your API key and base URL so that you can access Qualtrics programmatically.\nThe API key is as good as a password, so care should be taken to not share it publicly. For example, you would never want to save it in a script. The function below is the rare exception of code that should be run in the console and not saved. It works in a way that you only need to run it once, unless you are working on a new computer or your credentials changed. Note that in this book, we have not shared the actual API key, for the reasons outlined above. You should have an e-mail with the API key in it. Copy and paste it as a string to the api_key argument in the function below:\n\nqualtrics_api_credentials(api_key = \"\", base_url = \"ucsb.co1.qualtrics.com\", install = TRUE)\n\n\n\nAside\nThe .Renviron file is a special user controlled file that can create environment variables. Every time you open Rstudio, the variables in your environment file are loaded as…environment variables! Environment variables are named values that are accessible by your R process. They will not show up in your environment pane, but you can get a list of all of them using Sys.getenv(). Many are system defaults.\n\n\n\nTo view or edit your .Renviron file, you can use usethis::edit_r_environ().\nTo get a list of all the surveys in your Qualtrics instance, use the all_surveys function.\n\nsurveys <- all_surveys()\nkable(surveys) %>%\n kable_styling()\n\nThis function returns a list of surveys, in this case only one, and information about each, including an identifier and it’s name. We’ll need that identifier later, so let’s go ahead and extract it using base R from the data frame.\n\ni <- which(surveys$name == \"Survey for Data Science Training\")\nid <- surveys$id[i]\n\nYou can retrieve a list of the questions the survey asked using the survey_questions function and the survey id.\n\nquestions <- survey_questions(id)\nkable(questions) %>%\n kable_styling()\n\nThis returns a data.frame with one row per question with columns for question id, question name, question text, and whether the question was required. This is helpful to have as a reference for when you are looking at the full survey results.\nTo get the full survey results, run fetch_survey with the survey id.\n\nsurvey_results <- fetch_survey(id)\n\nThe survey results table has tons of information in it, not all of which will be relevant depending on your survey. The table has identifying information for the respondents (eg: ResponseID, IPaddress, RecipientEmail, RecipientFirstName, etc), much of which will be empty for this survey since it is anonymous. It also has information about the process of taking the survey, such as the StartDate, EndDate, Progress, and Duration. Finally, there are the answers to the questions asked, with columns labeled according to the qname column in the questions table (eg: Q1, Q2, Q3). Depending on the type of question, some questions might have multiple columns associated with them. We’ll have a look at this more closely in a later example.\n\n\nQuestion 2\nLet’s look at the responses to the second question in the survey, “How long have you been programming?” Remember, the first question was the consent question.\nWe’ll use the dplyr and tidyr tools we learned earlier to extract the information. Here are the steps:\n\nselect the column we want (Q1)\ngroup_by and summarize the values\n\n\nq2 <- survey_results %>% \n select(Q2) %>% \n group_by(Q2) %>% \n summarise(n = n())\n\nWe can show these results in a table using the kable function from the knitr package:\n\nkable(q2, col.names = c(\"How long have you been programming?\",\n \"Number of responses\")) %>%\n kable_styling()\n\n\n\n13.0.3.2 Question 3\nFor question 3, we’ll use a similar workflow. For this question, however there are two columns containing survey answers. One contains the answers from the controlled vocabulary, the other contains any free text answers users entered.\nTo present this information, we’ll first show the results of the controlled answers as a plot. Below the plot, we’ll include a table showing all of the free text answers for the “other” option.\n\nq3 <- survey_results %>% \n select(Q3) %>% \n group_by(Q3) %>% \n summarise(n = n())\n\n\nggplot(data = q3, mapping = aes(x = Q3, y = n)) +\n geom_col() +\n labs(x = \"What language do you currently use most frequently?\", y = \"Number of reponses\") +\n theme_minimal()\n\nNow we’ll extract the free text responses:\n\nq3_text <- survey_results %>% \n select(Q3_7_TEXT) %>% \n drop_na()\n\nkable(q3_text, col.names = c(\"Other responses to 'What language do you currently use mose frequently?'\")) %>% \n kable_styling()\n\n\n\n13.0.3.3 Question 4\nThe last question is just a free text question, so we can just display the results as is.\n\nq4 <- survey_results %>% \n select(Q4) %>% \n rename(`What data science tool or language are you most excited to learn next?` = Q4) %>% \n drop_na()\n\nkable(q4, col.names = \"What data science tool or language are you most excited to learn next?\") %>% \n kable_styling()\n\n\n\n\n13.0.4 Other survey tools\n\nGoogle forms\nGoogle forms can be a great way to set up surveys, and it is very easy to interact with the results using R. The benefits of using google forms are a simple interface and easy sharing between collaborators, especially when writing the survey instrument.\nThe downside is that google forms has far fewer features than Qualtrics in terms of survey flow and appearance.\nTo show how we can link R into our survey workflows, I’ve set up a simple example survey here.\nI’ve set up the results so that they are in a new spreadsheet here:. To access them, we will use the googlesheets4 package.\nFirst, open up a new R script and load the googlesheets4 library:\n\nlibrary(googlesheets4)\n\nNext, we can read the sheet in using the same URL that you would use to share the sheet with someone else. Right now, this sheet is public\n\nresponses <- read_sheet(\"https://docs.google.com/spreadsheets/d/1CSG__ejXQNZdwXc1QK8dKouxphP520bjUOnZ5SzOVP8/edit?usp=sharing\")\n\n✔ Reading from \"Example Survey Form (Responses)\".\n\n\n✔ Range 'Form Responses 1'.\n\n\nThe first time you run this, you should get a popup window in your web browser asking you to confirm that you want to provide access to your google sheets via the tidyverse (googlesheets) package.\nMy dialog box looked like this:\n\nMake sure you click the third check box enabling the Tidyverse API to see, edit, create, and delete your sheets. Note that you will have to tell it to do any of these actions via the R code you write.\nWhen you come back to your R environment, you should have a data frame containing the data in your sheet! Let’s take a quick look at the structure of that sheet.\n\ndplyr::glimpse(responses)\n\nRows: 10\nColumns: 5\n$ Timestamp <dttm> 2022-04-15 13:…\n$ `To what degree did the event meet your expectations?` <chr> \"Met expectatio…\n$ `To what degree did your knowledge improve?` <chr> \"Increase\", \"Si…\n$ `What did you like most about the event?` <chr> \"the cool instr…\n$ `What might you change about the event?` <chr> \"more snacks\", …\n\n\nSo, now that we have the data in a standard R data.frame, we can easily summarize it and plot results. By default, the column names in the sheet are the long fully descriptive questions that were asked, which can be hard to type. We can save those questions into a vector for later reference, like when we want to use the question text for plot titles.\n\nquestions <- colnames(responses)[2:5]\ndplyr::glimpse(questions)\n\n chr [1:4] \"To what degree did the event meet your expectations?\" ...\n\n\nWe can make the responses data frame more compact by renaming the columns of the vector with short numbered names of the form Q1. Note that, by using a sequence, this should work for sheets from just a few columns to many hundreds of columns, and provides a consistent question naming convention.\n\nnames(questions) <- paste0(\"Q\", seq(1:4))\ncolnames(responses) <- c(\"Timestamp\", names(questions))\ndplyr::glimpse(responses)\n\nRows: 10\nColumns: 5\n$ Timestamp <dttm> 2022-04-15 13:48:58, 2022-04-15 13:49:43, 2022-04-15 13:50:…\n$ Q1 <chr> \"Met expectations\", \"Above expectations\", \"Above expectation…\n$ Q2 <chr> \"Increase\", \"Significant increase\", \"Significant increase\", …\n$ Q3 <chr> \"the cool instructors\", \"R is rad!\", \"everything\", \"the pizz…\n$ Q4 <chr> \"more snacks\", \"no pineapple pizza!\", \"nothing\", \"needs more…\n\n\nNow that we’ve renamed our columns, let’s summarize the responses for the first question. We can use the same pattern that we usually do to split the data from Q1 into groups, then summarize it by counting the number of records in each group, and then merge the count of each group back together into a summarized data frame. We can then plot the Q1 results using ggplot:\n\nq1 <- responses %>% \n dplyr::select(Q1) %>% \n dplyr::group_by(Q1) %>% \n dplyr::summarise(n = dplyr::n())\n\nggplot2::ggplot(data = q1, mapping = aes(x = Q1, y = n)) +\n geom_col() +\n labs(x = questions[1], \n y = \"Number of reponses\",\n title = \"To what degree did the course meet expectations?\") +\n theme_minimal()\n\n\nBypassing authentication for public sheets\nIf you don’t want to go through a little interactive dialog every time you read in a sheet, and your sheet is public, you can run the function gs4_deauth() to access the sheet as a public user. This is helpful for cases when you want to run your code non-interactively. This is actually how I set it up for this book to build!\n\n\nChallenge\nNow that you have some background in accessing survey data from common tools, let’s do a quick exercise with Google Sheets. First, create a google sheet with the following columns that reflect a hypothetical survey result:\n\nTimestamp\nQ1: How much did your proficiency with survey tools in R change? 1 = None, 2 = A little, 3 = A lot\nQ2: How many years or partial years had you used R prior to this course?\nQ3: How many years or partial years had you used statistics before this course?\n\nNext populate the spreadhsheet with 5 to 10 rows of sample data that you make up. Now that you have the Google sheet in place, copy its URL and use it to do the following in R:\n\nLoad the google sheet into an R data.frame using the googlesheets package\nSave the column headers as a vector of questions\nRename the question columns with short, consistent names\nSummarize and plot the results for Q1 as a bar chart.\n\n\n\n\nSurvey Monkey\nSimilar to Qualtrics and qualtRics, there is an open source R package for working with data in Survey Monkey: Rmonkey. However, the last updates were made 5 years ago, an eternity in the software world, so it may or may not still function as intended.\nThere are also commercial options available. For example, cdata have a driver and R package that enable access to an analysis of Survey Monkey data through R." + }, + { + "objectID": "session_14.html", + "href": "session_14.html", + "title": "14  Guest Speaker", + "section": "", + "text": "Add material" + }, + { + "objectID": "session_16.html", + "href": "session_16.html", + "title": "16  Shiny", + "section": "", + "text": "16.0.1 Learning Objectives\nIn this lesson we will:\n\nreview the capabilities in Shiny applications\nlearn about the basic layout for Shiny interfaces\nlearn about the server component for Shiny applications\nbuild a simple shiny application for interactive plotting\n\n\n\n16.0.2 Overview\nShiny is an R package for creating interactive data visualizations embedded in a web application that you and your colleagues can view with just a web browser. Shiny apps are relatively easy to construct, and provide interactive features for letting others share and explore data and analyses.\nThere are some really great examples of what Shiny can do on the RStudio webite like this one exploring movie metadata. A more scientific example is a tool from the SASAP project exploring proposal data from the Alaska Board of Fisheries. There is also an app for Delta monitoring efforts.\n\nMost any kind of analysis and visualization that you can do in R can be turned into a useful interactive visualization for the web that lets people explore your data more intuitively But, a Shiny application is not the best way to preserve or archive your data. Instead, for preservation use a repository that is archival in its mission like the KNB Data Repository, Zenodo, or Dryad. This will assign a citable identifier to the specific version of your data, which you can then read in an interactive visualiztion with Shiny.\nFor example, the data for the Alaska Board of Fisheries application is published on the KNB and is citable as:\nMeagan Krupa, Molly Cunfer, and Jeanette Clark. 2017. Alaska Board of Fisheries Proposals 1959-2016. Knowledge Network for Biocomplexity. doi:10.5063/F1QN652R.\nWhile that is the best citation and archival location of the dataset, using Shiny, one can also provide an easy-to-use exploratory web application that you use to make your point that directly loads the data from the archival site. For example, the Board of Fisheries application above lets people who are not inherently familiar with the data to generate graphs showing the relationships between the variables in the dataset.\nWe’re going to create a simple shiny app with two sliders so we can interactively control inputs to an R function. These sliders will allow us to interactively control a plot.\n\n\n16.0.3 Create a sample shiny application\n\nFile > New > Shiny Web App…\nSet some fields: \n\nName it “myapp” or something else\nSelect “Single File”\nChoose to create it in a new folder called ‘shiny-demo’\nClick Create\n\n\nRStudio will create a new file called app.R that contains the Shiny application.\nRun it by choosing Run App from the RStudio editor header bar. This will bring up the default demo Shiny application, which plots a histogram and lets you control the number of bins in the plot.\n\nNote that you can drag the slider to change the number of bins in the histogram.\n\n\n16.0.4 Shiny architecture\nA Shiny application consists of two functions, the ui and the server. The ui function is responsible for drawing the web page, while the server is responsible for any calculations and for creating any dynamic components to be rendered.\nEach time that a user makes a change to one of the interactive widgets, the ui grabs the new value (say, the new slider min and max) and sends a request to the server to re-render the output, passing it the new input values that the user had set. These interactions can sometimes happen on one computer (e.g., if the application is running in your local RStudio instance). Other times, the ui runs on the web browser on one computer, while the server runs on a remote computer somewhere else on the Internet (e.g., if the application is deployed to a web server).\n\n\n\n16.0.5 Interactive scatterplots\nLet’s modify this application to plot Yolo bypass secchi disk data in a time-series, and allow aspects of the plot to be interactively changed.\n\n16.0.5.1 Load data for the example\nUse this code to load the data at the top of your app.R script. Note we are using contentId again, and we have filtered for some species of interest.\n\nlibrary(shiny)\nlibrary(contentid)\nlibrary(dplyr)\nlibrary(ggplot2)\nlibrary(lubridate)\n\nsha1 <- 'hash://sha1/317d7f840e598f5f3be732ab0e04f00a8051c6d0'\ndelta.file <- contentid::resolve(sha1, registries=c(\"dataone\"), store = TRUE)\n\n# fix the sample date format, and filter for species of interest\ndelta_data <- read.csv(delta.file) %>% \n mutate(SampleDate = mdy(SampleDate)) %>% \n filter(grepl(\"Salmon|Striped Bass|Smelt|Sturgeon\", CommonName))\n\nnames(delta_data)\n\n\n\n16.0.5.2 Add a simple timeseries using ggplot\nWe know there has been a lot of variation through time in the delta, so let’s plot a time-series of Secchi depth. We do so by switching out the histogram code for a simple ggplot, like so:\n\nserver <- function(input, output) {\n \n output$distPlot <- renderPlot({\n \n ggplot(delta_data, mapping = aes(SampleDate, Secchi)) +\n geom_point(colour=\"red\", size=4) +\n theme_light()\n })\n}\n\nIf you now reload the app, it will display the simple time-series instead of the histogram. At this point, we haven’t added any interactivity.\nIn a Shiny application, the server function provides the part of the application that creates our interactive components, and returns them to the user interface (ui) to be displayed on the page.\n\n\n16.0.5.3 Add sliders to set the start and end date for the X axis\nTo make the plot interactive, first we need to modify our user interface to include widgits that we’ll use to control the plot. Specifically, we will add a new slider for setting the minDate parameter, and modify the existing slider to be used for the maxDate parameter. To do so, modify the sidebarPanel() call to include two sliderInput() function calls:\n\nsidebarPanel(\n sliderInput(\"minDate\",\n \"Min Date:\",\n min = as.Date(\"1998-01-01\"),\n max = as.Date(\"2020-01-01\"),\n value = as.Date(\"1998-01-01\")),\n sliderInput(\"maxDate\",\n \"Max Date:\",\n min = as.Date(\"1998-01-01\"),\n max = as.Date(\"2020-01-01\"),\n value = as.Date(\"2005-01-01\"))\n)\n\nIf you reload the app, you’ll see two new sliders, but if you change them, they don’t make any changes to the plot. Let’s fix that.\n\n\n16.0.5.4 Connect the slider values to the plot\nFinally, to make the plot interactive, we can use the input and output variables that are passed into the server function to access the current values of the sliders. In Shiny, each UI component is given an input identifier when it is created, which is used as the name of the value in the input list. So, we can access the minimum depth as input$minDate and the max as input$maxDate. Let’s use these values now by adding limits to our X axis in the ggplot:\n\n ggplot(delta_data, mapping = aes(SampleDate, Secchi)) +\n geom_point(colour=\"red\", size=4) +\n xlim(c(input$minDate,input$maxDate)) +\n theme_light()\n\nAt this point, we have a fully interactive plot, and the sliders can be used to change the min and max of the Depth axis.\n\nLooks so shiny!\n\n\n16.0.5.5 Reversed Axes?\nWhat happens if a clever user sets the minimum for the X axis at a greater value than the maximum? You’ll see that the direction of the X axis becomes reversed, and the plotted points display right to left. This is really an error condition. Rather than use two independent sliders, we can modify the first slider to output a range of values, which will prevent the min from being greater than the max. You do so by setting the value of the slider to a vector of length 2, representing the default min and max date for the slider, such as c(as.Date(\"1998-01-01\"), as.Date(\"2020-01-01\")). So, delete the second slider, rename the first, and provide a vector for the value, like this:\n\nsliderInput(\"date\",\n \"Date:\",\n min = as.Date(\"1998-01-01\"),\n max = as.Date(\"2020-01-01\"),\n value = c(as.Date(\"1998-01-01\"), as.Date(\"2020-01-01\")))\n)\n\nNow, modify the ggplot to use this new date slider value, which now will be returned as a vector of length 2. The first element of the depth vector is the min, and the second is the max value on the slider.\n\n ggplot(delta_data, mapping = aes(SampleDate, Secchi)) +\n geom_point(colour=\"red\", size=4) +\n xlim(c(input$date[1],input$date[2])) +\n theme_light()\n\n\n\n\n\n16.0.6 Extending the user interface with dynamic plots\nIf you want to display more than one plot in your application, and provide a different set of controls for each plot, the current layout would be too simple. Next we will extend the application to break the page up into vertical sections, and add a new plot in which the user can choose which variables are plotted. The current layout is set up such that the FluidPage contains the title element, and then a sidebarLayout, which is divided horizontally into a sidebarPanel and a mainPanel.\n\n\n16.0.6.1 Vertical layout\nTo extend the layout, we will first nest the existing sidebarLayout in a new verticalLayout, which simply flows components down the page vertically. Then we will add a new sidebarLayout to contain the bottom controls and graph.\n\nThis mechanism of alternately nesting vertical and horizontal panels can be used to segment the screen into boxes with rules about how each of the panels is resized, and how the content flows when the browser window is resized. The sidebarLayout works to keep the sidebar about 1/3 of the box, and the main panel about 2/3, which is a good proportion for our controls and plots. Add the verticalLayout, and the second sidebarLayout for the second plot as follows:\n\n verticalLayout(\n # Sidebar with a slider input for depth axis\n sidebarLayout(\n sidebarPanel(\n sliderInput(\"date\",\n \"Date:\",\n min = as.Date(\"1998-01-01\"),\n max = as.Date(\"2020-01-01\"),\n value = c(as.Date(\"1998-01-01\"), as.Date(\"2020-01-01\")))\n ),\n # Show a plot of the generated distribution\n mainPanel(\n plotOutput(\"distPlot\")\n )\n ),\n\n tags$hr(),\n\n sidebarLayout(\n sidebarPanel(\n selectInput(\"x_variable\", \"X Variable\", cols, selected = \"SampleDate\"),\n selectInput(\"y_variable\", \"Y Variable\", cols, selected = \"Count\"),\n selectInput(\"color_variable\", \"Color\", cols, selected = \"CommonName\")\n ),\n\n # Show a plot with configurable axes\n mainPanel(\n plotOutput(\"varPlot\")\n )\n ),\n tags$hr()\n\nNote that the second sidebarPanel uses three selectInput elements to provide dropdown menus with the variable columns (cols) from our data frame. To manage that, we need to first set up the cols variable, which we do by saving the variables names from the delta_data data frame to a variable:\n\nsha1 <- 'hash://sha1/317d7f840e598f5f3be732ab0e04f00a8051c6d0'\ndelta.file <- contentid::resolve(sha1, registries=c(\"dataone\"), store = TRUE)\n\n# fix the sample date format, and filter for species of interest\ndelta_data <- read.csv(delta.file) %>% \n mutate(SampleDate = mdy(SampleDate)) %>% \n filter(grepl(\"Salmon|Striped Bass|Smelt|Sturgeon\", CommonName))\n\ncols <- names(delta_data)\n\n\n\n16.0.6.2 Add the dynamic plot\nBecause we named the second plot varPlot in our UI section, we now need to modify the server to produce this plot. Its very similar to the first plot, but this time we want to use the selected variables from the user controls to choose which variables are plotted. These variable names from the $input are character strings, and so would not be recognized as symbols in the aes mapping in ggplot. As recommended by the tidyverse authors, we use the non-standard evaluation syntax of .data[[\"colname\"]] to access the variables.\n\n output$varPlot <- renderPlot({\n ggplot(delta_data, aes(x = .data[[input$x_variable]],\n y = .data[[input$y_variable]],\n color = .data[[input$color_variable]])) +\n geom_point(size = 4)+\n theme_light()\n })\n\n\n\n\n16.0.7 Finishing touches: data citation\nCiting the data that we used for this application is the right thing to do, and easy. You can add arbitrary HTML to the layout using utility functions in the tags list.\n\n # Application title\n titlePanel(\"Yolo Bypass Fish and Water Quality Data\"),\n p(\"Data for this application are from: \"),\n tags$ul(\n tags$li(\"Interagency Ecological Program: Fish catch and water quality data from the Sacramento River floodplain and tidal slough, collected by the Yolo Bypass Fish Monitoring Program, 1998-2018.\",\n tags$a(\"doi:10.6073/pasta/b0b15aef7f3b52d2c5adc10004c05a6f\", href=\"http://doi.org/10.6073/pasta/b0b15aef7f3b52d2c5adc10004c05a6f\")\n )\n ),\n tags$br(),\n tags$hr(),\n\nThe final application shows the data citation, the depth plot, and the configurable scatterplot in three distinct panels.\n\n\n\n16.0.8 Publishing Shiny applications\nOnce you’ve finished your app, you’ll want to share it with others. To do so, you need to publish it to a server that is set up to handle Shiny apps.\nYour main choices are:\n\nshinyapps.io (Hosted by RStudio)\n\nThis is a service offered by RStudio, which is initially free for 5 or fewer apps and for limited run time, but has paid tiers to support more demanding apps. You can deploy your app using a single button push from within RStudio.\n\nShiny server (On premises)\n\nThis is an open source server which you can deploy for free on your own hardware. It requires more setup and configuration, but it can be used without a fee.\n\nRStudio connect (On premises)\n\nThis is a paid product you install on your local hardware, and that contains the most advanced suite of services for hosting apps and RMarkdown reports. You can publish using a single button click from RStudio.\n\n\nA comparison of publishing features is available from RStudio.\n\n16.0.8.1 Publishing to shinyapps.io\nThe easiest path is to create an account on shinyapps.io, and then configure RStudio to use that account for publishing. Instructions for enabling your local RStudio to publish to your account are displayed when you first log into shinyapps.io:\n\nOnce your account is configured locally, you can simply use the Publish button from the application window in RStudio, and your app will be live before you know it!\n\n\n\n\n16.0.9 Summary\nShiny is a fantastic way to quickly and efficiently provide data exploration for your data and code. We highly recommend it for its interactivity, but an archival-quality repository is the best long-term home for your data and products. In this example, we used data drawn directly from the EDI repository in our Shiny app, which offers both the preservation guarantees of an archive, plus the interactive data exploration from Shiny. You can utilize the full power of R and the tidyverse for writing your interactive applications.\n\n\n16.0.10 Full source code for the final application\n\nlibrary(shiny)\nlibrary(contentid)\nlibrary(dplyr)\nlibrary(ggplot2)\nlibrary(lubridate)\n\n# read in the data from EDI\nsha1 <- 'hash://sha1/317d7f840e598f5f3be732ab0e04f00a8051c6d0'\ndelta.file <- contentid::resolve(sha1, registries=c(\"dataone\"), store = TRUE)\n\n# fix the sample date format, and filter for species of interest\ndelta_data <- read.csv(delta.file) %>% \n mutate(SampleDate = mdy(SampleDate)) %>% \n filter(grepl(\"Salmon|Striped Bass|Smelt|Sturgeon\", CommonName))\n\ncols <- names(delta_data)\n \n\n\n# Define UI for application that draws a two plots\nui <- fluidPage(\n \n # Application title and data source\n titlePanel(\"Sacramento River floodplain fish and water quality dataa\"),\n p(\"Data for this application are from: \"),\n tags$ul(\n tags$li(\"Interagency Ecological Program: Fish catch and water quality data from the Sacramento River floodplain and tidal slough, collected by the Yolo Bypass Fish Monitoring Program, 1998-2018.\",\n tags$a(\"doi:10.6073/pasta/b0b15aef7f3b52d2c5adc10004c05a6f\", href=\"http://doi.org/10.6073/pasta/b0b15aef7f3b52d2c5adc10004c05a6f\")\n )\n ),\n tags$br(),\n tags$hr(),\n \n verticalLayout(\n # Sidebar with a slider input for time axis\n sidebarLayout(\n sidebarPanel(\n sliderInput(\"date\",\n \"Date:\",\n min = as.Date(\"1998-01-01\"),\n max = as.Date(\"2020-01-01\"),\n value = c(as.Date(\"1998-01-01\"), as.Date(\"2020-01-01\")))\n ),\n # Show a plot of the generated timeseries\n mainPanel(\n plotOutput(\"distPlot\")\n )\n ),\n \n tags$hr(),\n \n sidebarLayout(\n sidebarPanel(\n selectInput(\"x_variable\", \"X Variable\", cols, selected = \"SampleDate\"),\n selectInput(\"y_variable\", \"Y Variable\", cols, selected = \"Count\"),\n selectInput(\"color_variable\", \"Color\", cols, selected = \"CommonName\")\n ),\n \n # Show a plot with configurable axes\n mainPanel(\n plotOutput(\"varPlot\")\n )\n ),\n tags$hr()\n )\n)\n\n# Define server logic required to draw the two plots\nserver <- function(input, output) {\n \n # turbidity plot\n output$distPlot <- renderPlot({\n \n ggplot(delta_data, mapping = aes(SampleDate, Secchi)) +\n geom_point(colour=\"red\", size=4) +\n xlim(c(input$date[1],input$date[2])) +\n theme_light()\n })\n \n # mix and match plot\n output$varPlot <- renderPlot({\n ggplot(delta_data, aes(x = .data[[input$x_variable]],\n y = .data[[input$y_variable]],\n color = .data[[input$color_variable]])) +\n geom_point(size = 4) +\n theme_light()\n })\n}\n\n\n# Run the application \nshinyApp(ui = ui, server = server)\n\n\n\n16.0.11 A shinier app with tabs and a map!\n\nlibrary(shiny)\nlibrary(contentid)\nlibrary(dplyr)\nlibrary(tidyr)\nlibrary(ggplot2)\nlibrary(lubridate)\nlibrary(shinythemes)\nlibrary(sf)\nlibrary(leaflet)\nlibrary(snakecase)\n\n# read in the data from EDI\nsha1 <- 'hash://sha1/317d7f840e598f5f3be732ab0e04f00a8051c6d0'\ndelta.file <- contentid::resolve(sha1, registries=c(\"dataone\"), store = TRUE)\n\n# fix the sample date format, and filter for species of interest\ndelta_data <- read.csv(delta.file) %>% \n mutate(SampleDate = mdy(SampleDate)) %>% \n filter(grepl(\"Salmon|Striped Bass|Smelt|Sturgeon\", CommonName)) %>% \n rename(DissolvedOxygen = DO,\n Ph = pH,\n SpecificConductivity = SpCnd)\n\ncols <- names(delta_data)\n\nsites <- delta_data %>% \n distinct(StationCode, Latitude, Longitude) %>% \n drop_na() %>% \n st_as_sf(coords = c('Longitude','Latitude'), crs = 4269, remove = FALSE)\n\n\n\n# Define UI for application\nui <- fluidPage(\n navbarPage(theme = shinytheme(\"flatly\"), collapsible = TRUE,\n HTML('<a style=\"text-decoration:none;cursor:default;color:#FFFFFF;\" class=\"active\" href=\"#\">Sacramento River Floodplain Data</a>'), id=\"nav\",\n windowTitle = \"Sacramento River floodplain fish and water quality data\",\n \n tabPanel(\"Data Sources\",\n verticalLayout(\n # Application title and data source\n titlePanel(\"Sacramento River floodplain fish and water quality data\"),\n p(\"Data for this application are from: \"),\n tags$ul(\n tags$li(\"Interagency Ecological Program: Fish catch and water quality data from the Sacramento River floodplain and tidal slough, collected by the Yolo Bypass Fish Monitoring Program, 1998-2018.\",\n tags$a(\"doi:10.6073/pasta/b0b15aef7f3b52d2c5adc10004c05a6f\", href=\"http://doi.org/10.6073/pasta/b0b15aef7f3b52d2c5adc10004c05a6f\")\n )\n ),\n tags$br(),\n tags$hr(),\n p(\"Map of sampling locations\"),\n mainPanel(leafletOutput(\"map\"))\n )\n ),\n \n tabPanel(\n \"Explore\",\n verticalLayout(\n mainPanel(\n plotOutput(\"distPlot\"),\n width = 12,\n absolutePanel(id = \"controls\",\n class = \"panel panel-default\",\n top = 175, left = 75, width = 300, fixed=TRUE,\n draggable = TRUE, height = \"auto\",\n sliderInput(\"date\",\n \"Date:\",\n min = as.Date(\"1998-01-01\"),\n max = as.Date(\"2020-01-01\"),\n value = c(as.Date(\"1998-01-01\"), as.Date(\"2020-01-01\")))\n \n )\n ),\n \n tags$hr(),\n \n sidebarLayout(\n sidebarPanel(\n selectInput(\"x_variable\", \"X Variable\", cols, selected = \"SampleDate\"),\n selectInput(\"y_variable\", \"Y Variable\", cols, selected = \"Count\"),\n selectInput(\"color_variable\", \"Color\", cols, selected = \"CommonName\")\n ),\n \n # Show a plot with configurable axes\n mainPanel(\n plotOutput(\"varPlot\")\n )\n ),\n tags$hr()\n )\n )\n )\n)\n\n# Define server logic required to draw the two plots\nserver <- function(input, output) {\n \n \n output$map <- renderLeaflet({leaflet(sites) %>% \n addTiles() %>% \n addCircleMarkers(data = sites,\n lat = ~Latitude,\n lng = ~Longitude,\n radius = 10, # arbitrary scaling\n fillColor = \"gray\",\n fillOpacity = 1,\n weight = 0.25,\n color = \"black\",\n label = ~StationCode)\n })\n \n # turbidity plot\n output$distPlot <- renderPlot({\n \n ggplot(delta_data, mapping = aes(SampleDate, Secchi)) +\n geom_point(colour=\"red\", size=4) +\n xlim(c(input$date[1],input$date[2])) +\n labs(x = \"Sample Date\", y = \"Secchi Depth (m)\") +\n theme_light()\n })\n \n # mix and match plot\n output$varPlot <- renderPlot({\n ggplot(delta_data, mapping = aes(x = .data[[input$x_variable]],\n y = .data[[input$y_variable]],\n color = .data[[input$color_variable]])) +\n labs(x = to_any_case(input$x_variable, case = \"title\"),\n y = to_any_case(input$y_variable, case = \"title\"),\n color = to_any_case(input$color_variable, case = \"title\")) +\n geom_point(size=4) +\n theme_light()\n })\n}\n\n\n# Run the application \nshinyApp(ui = ui, server = server)\n\n\n\n16.0.12 Resources\n\nMain Shiny site\nOfficial Shiny Tutorial" + }, + { + "objectID": "session_17.html", + "href": "session_17.html", + "title": "17  Appendix", + "section": "", + "text": "Configuring Two-factor Authentication on GitHub" + }, + { + "objectID": "session_17.html#learning-objectives", + "href": "session_17.html#learning-objectives", + "title": "17  Appendix", + "section": "Learning Objectives", + "text": "Learning Objectives\n\nSuccessfully setup two-factor authentication on GitHub\nRecognize two-factor authentication jargon" + }, + { + "objectID": "session_17.html#why-set-up-two-factor-authentication-2fa", + "href": "session_17.html#why-set-up-two-factor-authentication-2fa", + "title": "17  Appendix", + "section": "17.1 Why Set up Two-factor Authentication (2FA)", + "text": "17.1 Why Set up Two-factor Authentication (2FA)\n\nPrevents unauthorized access\nStrengthens your web security, especially if you have a compromised password\nIt is an increasing requirement for most websites and online applications or services\n\nIn March 2023, GitHub announced that it will require 2FA for “all developers who contribute code on GitHub.com” (GitHub Blog). This rollout will be completed by the end of 2023.\nAll users have the flexibility to use their preferred 2FA method, including: TOTP, SMS, security keys, or GitHub Mobile app. GitHub strongly recommends using security keys and TOTPs. While SMS-based 2FA is available to use, it does not provide the same level of protection, and is no longer recommended under NIST (National Institute of Standards and Technology) 800-63B.\n\n17.1.1 Additional information about 2FA on GitHub:\n\nSecuring your account with two-factor authentication (2FA)\nConfiguring two-factor authentication\nRaising the bar for software security: GitHub 2FA begins March 13\nSoftware security starts with the developer: Securing developer accounts with 2FA\n\n\n\n\n\n\n\nFor Your Reference\n\n\n\nReview the Glossary table to see a comprehensive list of two-factor authentication related terms and definitions" + }, + { + "objectID": "session_17.html#steps-for-configuring-2fa-using-a-totp-app", + "href": "session_17.html#steps-for-configuring-2fa-using-a-totp-app", + "title": "17  Appendix", + "section": "17.2 Steps for Configuring 2FA Using a TOTP App", + "text": "17.2 Steps for Configuring 2FA Using a TOTP App\n\n\n\n\n\n\nAdditional Resource\n\n\n\nGitHub outlines these steps online in an article: Configuring two-factor authentication.\n\n\n\nDownload a TOTP app\nNavigate to your account Settings (click your profile photo in the top right-hand corner)\nIn the “Access” section, click “Password and Authenticate”\nIn the “Two-factor authentication” section, click Enable two-factor authentication\nUnder “Setup authenticator app”, either:\n\nScan the QR code with your TOTP app. After scanning, the app displays a six-digit code that you can enter on GitHub\nIf you can’t scan the QR code, click “enter this text code” to see a code that you can manually enter in your TOTP app instead\n\nOn GitHub, type the code into the field under “Verify the code from the app”\nUnder “Save your recovery codes”, click “Download” to download your recovery codes. Save them to a secure location because your recovery codes can help you get back into your account if you lose access.\n\nAfter saving your two-factor recovery codes, click “I have saved my recovery codes” to enable two-factor authentication for your account\n\nConfigure additional 2FA methods, if desired" + }, + { + "objectID": "session_17.html#glossary", + "href": "session_17.html#glossary", + "title": "17  Appendix", + "section": "17.3 Glossary", + "text": "17.3 Glossary\n\n\n\n\n\n\n\nTerm\nDefinition\n\n\n\n\nQuick Response (QR) Code\nA type of two-dimensional matrix barcode that contains specific information\n\n\nRecovery Code\nA unique code(s) used to reset passwords or regain access to accounts\n\n\nShort Message Service (SMS)\nA text messaging service that allows mobile devices to exchange short text messages\n\n\nTime-based one-time password (TOTP)\nA string of unique codes that changes based on time. Often, these appear as six-digit numbers that regenerate every 30 seconds\n\n\nTwo-factor Authentication (2FA)\nAn identity and access management security method that requires two forms of identification to access accounts, resources, or data" + } +] \ No newline at end of file diff --git a/public/session_01.html b/public/session_01.html new file mode 100644 index 00000000..d48f4c0b --- /dev/null +++ b/public/session_01.html @@ -0,0 +1,961 @@ + + + + + + + + + +NCEAS Open Science Synthesis for the Delta Science Program - 1  Collaborating using Git and GitHub & Merge Conflicts + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

1  Collaborating using Git and GitHub & Merge Conflicts

+
+
+ + +
+ + + + +
+ + +
+ + +
+ + + +
+ + + + +
+

Learning Objectives

+
    +
  • Apply the principles, features, and collaboration tools of Git and GitHub to effectively collaborate with colleagues on code
  • +
  • Analyze and evaluate common causes of conflicts that arise when collaborating on repositories
  • +
  • Demonstrate the ability to resolve conflicts using Git conflict resolution techniques
  • +
  • Apply workflows and best practices that minimize conflicts on collaborative repositories
  • +
+
+
+

1.1 Introduction to Git and GitHub Tools for Collaboration

+
+
+

+
Artwork by Allison Horst
+
+
+

Git is not only a powerful tool for individual work but also an excellent choice for collaborating with friends and colleagues. Git ensures that after you’ve completed your contributions to a repository, you can confidently synchronize your changes with changes made by others.

+

One of the easiest and most effective ways to collaborate using Git is by utilizing a shared repository on a hosting service like GitHub. This shared repository acts as a central hub, enabling collaborators to effortlessly exchange and merge their changes. With Git and a shared repository, you can collaborate seamlessly and work confidently, knowing that your changes will be integrated smoothly with those of your collaborators.

+
+
+

+
Graphic from Atlassian
+
+
+

There are many advanced techniques for synchronizing Git repositories, but let’s start with a simple example.

+

In this example, the Collaborator will clone a copy of the Owner’s repository from GitHub, and the Owner will grant them Collaborator status, enabling the Collaborator to directly pull and push from the Owner’s GitHub repository.

+
+
+

1.2 Collaborating with a trusted colleague without conflicts

+

We start our collaboration by giving a trusted colleague access to our repository on GitHub. In this example, we define the Owner as the individual who owns the repository, and the Collaborator as the person whom the Owner chooses to give permission to make changes to their repository.

+

The Collaborator will make changes to the repository and then push those changes to the shared repository on GitHub. The Owner will then use pull to retrieve the changes without encountering any conflicts. This is the most ideal workflow.

+

The instructors will demonstrate this process in the next section.

+
+

Step 0: Owner adds Collaborator to shared repository

+

The Owner must change the settings of the repository and give the Collaborator access to the repository by inviting them as a collaborator to the repository. Once the Collaborator has accepted the invite, they can contribute to the repository.

+
+
+

+
+
+
+
+

Step 1: Collaborator clone

+

To be able to contribute to a repository, the Collaborator must clone the repository from the Owner’s GitHub account. To do this, the Collaborator should visit the GitHub page for the Owner’s repository, and then copy the clone URL. In R Studio, the Collaborator will create a new project from version control by pasting this clone URL into the appropriate dialog (see the earlier chapter introducing GitHub).

+

+
+
+

Step 2: Collaborator edit

+

With a clone copied locally, the Collaborator can now make changes to the README.md file in the repository, adding a line or statement somewhere noticeable near the top. Save your changes.

+
+
+

Step 3: Collaborator commit and push

+

To sync changes, the Collaborator will need to add, commit, and push their changes to the Owner’s repository. But before doing so, it’s good practice to pull immediately before committing to ensure you have the most recent changes from the Owner. So, in RStudio’s Git tab, first click the “Diff” button to open the Git window, and then press the green “Pull” down arrow button. This will fetch any recent changes from the origin repository and merge them. Next, add the changed README.Rmd file to be committed by clicking the check box next to it, type in a commit message, and click “Commit”. Once that finishes, then the Collaborator can immediately click “Push” to send the commits to the Owner’s GitHub repository.

+
+
+

+
+
+
+
+

Step 4: Owner pull

+

Now, the Owner can open their local working copy of the code in RStudio, and pull those changes down to their local copy.

+

Congrats, the Owner now has your changes!

+
+
+

Step 5: Owner edits, commit, and push

+

Next, the Owner should do the same. Make changes to a file in the repository, save it, pull to make sure no new changes have been made while editing, and then add, commit, and push the Owner changes to GitHub.

+
+
+

Step 6: Collaborator pull

+

The Collaborator can now pull down those Owner changes, and all copies are once again fully synced. And you’re off to collaborating.

+
+
+
+

1.3 Exercise 1: With a partner collaborate in a repository without a merge conflict

+
+
+
+ +
+
+Setup +
+
+
+
    +
  • Get into pairs, then choose one person as the Owner and one as the Collaborator
  • +
  • Both logon to GitHub
  • +
+

These next steps are for the Owner:

+
    +
  • Navigate to the {FIRSTNAME}_test repository
  • +
  • Go to “Settings” and navigate to “Collaborators” in the “Access” section on the left-hand side
  • +
  • Under “Manage Access” click the button “Add people” and type the username of your Collaborator in the search box
  • +
  • Once you’ve found the correct username, click “Add {Collaborator username} to this repository
  • +
+
+
+

+
+
+

Now, the Collaborator will follow this step:

+
    +
  • Check your email for an invitation to GitHub or check your notifications (likely under “Your Organizations”) on GitHub to accept the invite to collaborate.
  • +
+
+
+
+
+
+ +
+
+Last thing, some Git configuration +
+
+
+

When Git released version 2.27, a new feature they incorporated allows users to specify how to pull, essentially, otherwise a warning will appear. To suppress this warning we need to configure our Git with this line of code:

+
git config pull.rebase false
+

pull.rebase false is a default strategy for pulling where it will try to auto-merge the files if possible, and if it can’t it will show a merge conflict

+
+
+
+
+
+ +
+
+Instructions +
+
+
+

You will do the exercise twice, where each person will get to practice being both the Owner and the Collaborator roles.

+
    +
  • Step 0: Designate one person as the Owner and one as the Collaborator.
  • +
+

Round One:

+
    +
  • Step 1: Owner adds Collaborator to {FIRSTNAME}_test repository (see Setup block above for detailed steps)
  • +
  • Step 2: Collaborator clones the Owner’s {FIRSTNAME}_test repository
  • +
  • Step 3: Collaborator edits the README file: +
      +
    • Collaborator adds a new level 2 heading to README titled “Git Workflow”
    • +
  • +
  • Step 4: Collaborator commits and pushes the README file with the new changes to GitHub
  • +
  • Step 5: Owner pulls the changes that the Collaborator made
  • +
  • Step 6: Owner edits the README file: +
      +
    • Under “Git Workflow”, Owner adds the steps of the Git workflow we’ve been practicing
    • +
  • +
  • Step 7: Owner commits and pushes the README file with the new changes to GitHub
  • +
  • Step 8: Collaborator pulls the Owners changes from GitHub
  • +
  • Step 9: Go back to Step 0, switch roles, and then follow the steps in Round Two.
  • +
+

Round Two:

+
    +
  • Step 1: Owner adds Collaborator to {FIRSTNAME}_test repository
  • +
  • Step 2: Collaborator clones the Owner’s {FIRSTNAME}_test repository
  • +
  • Step 3: Collaborator edits the README file: +
      +
    • Collaborator adds a new level 2 heading to README titled “How to Create a Git Repository from an existing project” and adds the high level steps for this workflow
    • +
  • +
  • Step 4: Collaborator commits and pushes the README file with the new changes to GitHub
  • +
  • Step 5: Owner pulls the changes that the Collaborator made
  • +
  • Step 6: Owner edits the README file: +
      +
    • Under “How to Create a Git Repository”, Owner adds the high level steps for this workflow
    • +
  • +
  • Step 7: Owner commits and pushes the README file with the new changes to GitHub
  • +
  • Step 8: Collaborator pulls the Owners changes from GitHub
  • +
+

Hint: If you don’t remember how to create a Git repository, refer to the chapter Intro to Git and GitHub where we created two Git repositories

+
+
+
+
+

1.4 A Note on Advanced Collaboration Techniques

+

There are many Git and GitHub collaboration techniques, some more advanced than others. We won’t be covering advanced strategies in this course. But here is a table for your reference on a few popular Git collaboration workflow strategies and tools.

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Collaboration TechniqueBenefitsWhen to UseWhen Not to Use
Branch Management Strategies1. Enables parallel development and experimentation
2. Facilitates isolation of features or bug fixes
3. Provides flexibility and control over project workflows
When working on larger projects with multiple features or bug fixes simultaneously.
When you want to maintain a stable main branch while developing new features or resolving issues on separate branches.
When collaborating with teammates on different aspects of a project and later integrating their changes.
When working on small projects with a single developer or limited codebase.
When the project scope is simple and doesn’t require extensive branch management.
When there is no need to isolate features or bug fixes.
Code Review Practices1. Enhances code quality and correctness through feedback
2. Promotes knowledge sharing and learning within the team
3. Helps identify bugs, improve performance, and ensure adherence to coding standards
When collaborating on a codebase with team members to ensure code quality and maintain best practices.
When you want to receive feedback and suggestions on your code to improve its readability, efficiency, or functionality.
When working on critical or complex code that requires an extra layer of scrutiny before merging it into the main branch.
When working on personal projects or small codebases with no collaboration involved.
When time constraints or project size make it impractical to conduct code reviews.
When the codebase is less critical or has low complexity.
Forking1. Enables independent experimentation and development
2. Provides a way to contribute to a project without direct access
3. Allows for creating separate, standalone copies of a repository
When you want to contribute to a project without having direct write access to the original repository.
When you want to work on an independent variation or extension of an existing project.
When experimenting with changes or modifications to a project while keeping the original repository intact.
When collaborating on a project with direct write access to the original repository.
When the project does not allow external contributions or forking.
When the project size or complexity doesn’t justify the need for independent variations.
Pull Requests1. Facilitates code review and discussion
2. Allows for collaboration and feedback from team members
3. Enables better organization and tracking of proposed changes
When working on a shared repository with a team and wanting to contribute changes in a controlled and collaborative manner.
When you want to propose changes to a project managed by others and seek review and approval before merging them into the main codebase.
When working on personal projects or individual coding tasks without the need for collaboration.
When immediate changes or fixes are required without review processes.
When working on projects with a small team or single developer with direct write access to the repository.
+

The “When Not to Use” column provides insights into situations where it may be less appropriate to use each collaboration technique, helping you make informed decisions based on the specific context and requirements of your project.

+

These techniques provide different benefits and are used in various collaboration scenarios, depending on the project’s needs and team dynamics.

+
+
+

1.5 Merge conflicts

+

Merge conflicts occur when both collaborators make conflicting changes to the same file. Resolving merge conflicts involves identifying the root of the problem and restoring the project to a normal state. Good communication, discussing file sections to work on, and avoiding overlaps can help prevent merge conflicts. However, if conflicts do arise, Git warns about potential issues and ensures that changes from different collaborators based on the same file version are not overwritten. To resolve conflicts, you need to explicitly specify whose changes should be used for each conflicting line in the file.

+

In this image, we see collaborators mbjones and metamattj have both made changes to the same line in the same README.md file. This is causing a merge conflict because Git doesn’t know whose changes came first. To resolve it, we need to tell Git whose changes to keep for that line, and whose changes to discard.

+

+
+

1.5.1 Common ways to resolve a merge conflict

+

1. Abort, abort, abort…

+

Sometimes you just made a mistake. When you get a merge conflict, the repository is placed in a “Merging” state until you resolve it. There’s a Terminal command to abort doing the merge altogether:

+
git merge --abort
+

Of course, after doing that you still haven’t synced with your Collaborator’s changes, so things are still unresolved. But at least your repository is now usable on your local machine.

+

2. Checkout

+

The simplest way to resolve a conflict, given that you know whose version of the file you want to keep, is to use the command line Git program to tell Git to use either your changes (the person doing the merge), or their changes (the Collaborator).

+
    +
  • keep your Collaborator’s file: git checkout --theirs conflicted_file.Rmd
  • +
  • keep your own file: git checkout --ours conflicted_file.Rmd
  • +
+

Once you have run that command, then run add (staging), commit, pull, and push the changes as normal.

+

3. Pull and edit the file

+

But that requires the command line. If you want to resolve from RStudio, or if you want to pick and choose some of your changes and some of your Collaborator’s, then instead you can manually edit and fix the file. When you pull the file with a conflict, Git notices that there is a conflict and modifies the file to show both your own changes and your Collaborator’s changes in the file. It also shows the file in the Git tab with an orange U icon, which indicates that the file is Unmerged, and therefore awaiting your help to resolve the conflict. It delimits these blocks with a series of less than and greater than signs, so they are easy to find:

+
+
+

+
+
+

To resolve the conflicts, simply find all of these blocks, and edit them so that the file looks how you want (either pick your lines, your Collaborator’s lines, some combination, or something altogether new), and save. Be sure you removed the delimiter lines that started with

+
    +
  • <<<<<<<,
  • +
  • =======,
  • +
  • and >>>>>>>.
  • +
+

Once you have made those changes, you simply add (staging), commit, and push the files to resolve the conflict.

+
+
+
+

1.6 Producing and resolving merge conflicts

+

To illustrate this process, the instructors are going to carefully create a merge conflict step by step, show how to resolve it, and show how to see the results of the successful merge after it is complete. First, the instructors will walk through the exercise to demonstrate the issues. Then, participants will pair up and try the exercise.

+
+

Step 1: Owner and Collaborator ensure all changes are updated

+

First, start the exercise by ensuring that both the Owner and Collaborator have all of the changes synced to their local copies of the Owner’s repository in RStudio. This includes doing a git pull to ensure that you have all changes local, and make sure that the Git tab in RStudio doesn’t show any changes needing to be committed.

+
+
+

Step 2: Owner makes a change and commits

+

From that clean slate, the Owner first modifies and commits a small change including their name on a specific line of the README.md file (we will change the first line, the title). Work to only change that one line, and add your username to the line in some form and commit the changes (but DO NOT push). We are now in a situation where the Owner has unpushed changes that the Collaborator can not yet see.

+
+
+

Step 3: Collaborator makes a change and commits on the same line

+

Now the Collaborator also makes changes to the same line (the first line, the title) on the README.md file in their RStudio copy of the project, adding their name to the line. They then commit. At this point, both the Owner and Collaborator have committed changes based on their shared version of the README.md file, but neither has tried to share their changes via GitHub.

+
+
+

Step 4: Collaborator pushes the file to GitHub

+

Sharing starts when the Collaborator pushes their changes to the GitHub repo, which updates GitHub to their version of the file. The Owner is now one revision behind, but doesn’t know it yet.

+
+
+

Step 5: Owner pushes their changes and gets an error

+

At this point, the Owner tries to push their change to the repository, which triggers an error from GitHub. While the error message is long, it basically tells you everything needed (that the Owner’s repository doesn’t reflect the changes on GitHub, and that they need to pull before they can push).

+

+
+
+

Step 6: Owner pulls from GitHub to get Collaborator changes

+

Doing what the message says, the Owner pulls the changes from GitHub, and gets another, different error message. In this case, it indicates that there is a merge conflict because of the conflicting lines.

+

+

In the Git pane of RStudio, the file is also flagged with an orange U, which stands for an unresolved merge conflict.

+

+
+
+

Step 7: Owner edits the file to resolve the conflict

+

To resolve the conflict, the Owner now needs to edit the file. Again, as indicated above, Git has flagged the locations in the file where a conflict occurred with <<<<<<<, =======, and >>>>>>>. The Owner should edit the file, merging whatever changes are appropriate until the conflicting lines read how they should, and eliminate all of the marker lines with <<<<<<<, =======, and >>>>>>>.

+

+

Of course, for scripts and programs, resolving the changes means more than just merging the text – whoever is doing the merging should make sure that the code runs properly and none of the logic of the program has been broken.

+

+
+
+

Step 8: Owner commits the resolved changes

+

From this point forward, things proceed as normal. The Owner first add the file changes to be made, which changes the orange U to a blue M for modified, and then commits the changes locally. The Owner now has a resolved version of the file on their system.

+

+
+
+

Step 9: Owner pushes the resolved changes to GitHub

+

Have the Owner push the changes, and it should replicate the changes to GitHub without error.

+

+
+
+

Step 10: Collaborator pulls the resolved changes from GitHub

+

Finally, the Collaborator can pull from GitHub to get the changes the Owner made.

+
+
+

Step 11: Both can view commit history

+

When either the Collaborator or the Owner view the history, the conflict, associated branch, and the merged changes are clearly visible in the history.

+

+
+
+
+

1.7 Exercise 2: With a partner collaborate in a repository and resolve a merge conflict

+

Note you will only need to complete the Setup and Git configuration steps again if you are working in a new repository. Return to Exercise 1 for Setup and Git configuration steps.

+
+
+
+ +
+
+Instructions +
+
+
+

Now it’s your turn. In pairs, intentionally create a merge conflict, and then go through the steps needed to resolve the issues and continue developing with the merged files. See the sections above for help with each of the steps below. You will do the exercise twice, where each person will get to practice being both the Owner and the Collaborator roles.

+
    +
  • Step 0: Designate one person as the Owner and one as the Collaborator.
  • +
+

Round One:

+
    +
  • Step 1: Both Owner and Collaborator pull to ensure both have the most up-to-date changes
  • +
  • Step 2: Owner edits the README file and makes a change to the title and commits do not push
  • +
  • Step 3: On the same line, Collaborator edits the README file and makes a change to the title and commits
  • +
  • Step 4: Collaborator pushes the file to GitHub
  • +
  • Step 5: Owner pushes their changes and gets an error
  • +
  • Step 6: Owner pulls from GitHub to get Collaborator changes
  • +
  • Step 7: Owner edits the README file to resolve the conflict
  • +
  • Step 8: Owner commits the resolved changes
  • +
  • Step 9: Owner pushes the resolved changes to GitHub
  • +
  • Step 10: Collaborator pulls the resolved changes from GitHub
  • +
  • Step 11: Both view commit history
  • +
  • Step 12: Go back to Step 0, switch roles, and then follow the steps in Round Two.
  • +
+

Round Two:

+
    +
  • Step 1: Both Owner and Collaborator pull to ensure both have the most up-to-date changes
  • +
  • Step 2: Owner edits the README file and makes a change to line 2 and commits do not push
  • +
  • Step 3: On the same line, Collaborator edits the README file and makes a change to line 2 and commits
  • +
  • Step 4: Collaborator pushes the file to GitHub
  • +
  • Step 5: Owner pushes their changes and gets an error
  • +
  • Step 6: Owner pulls from GitHub to get Collaborator changes
  • +
  • Step 7: Owner edits the README file to resolve the conflict
  • +
  • Step 8: Owner commits the resolved changes
  • +
  • Step 9: Owner pushes the resolved changes to GitHub
  • +
  • Step 10: Collaborator pulls the resolved changes from GitHub
  • +
  • Step 11: Both view commit history
  • +
+
+
+
+
+

1.8 Best practices to avoid merge conflicts

+

Some basic rules of thumb can avoid the vast majority of merge conflicts, saving a lot of time and frustration. These are words our teams live by:

+ +
+
+
+

+
XKCD 1597
+
+
+
    +
  • Communicate often and set up effective communication channels
  • +
  • Tell each other what you are working on
  • +
  • Start your working session with a pull
  • +
  • Pull immediately before you commit or push
  • +
  • Commit often in small chunks (this helps you organize your work!)
  • +
  • Make sure you and who you are collaborating with all fully understand the Git workflow you’re using aka make sure you’re on the same page before you start!
  • +
+

A good workflow is encapsulated as follows:

+

Pull -> Edit -> Save -> Add (stage) -> Commit -> Pull -> Push

+

Always start your working sessions with a pull to get any outstanding changes, then start your work. Stage your changes, but before you commit, pull again to see if any new changes have arrived. If so, they should merge in easily if you are working in different parts of the program. You can then commit and immediately push your changes safely.

+

Good luck, and try to not get frustrated. Once you figure out how to handle merge conflicts, they can be avoided or dispatched when they occur, but it does take a bit of practice.

+ + +
+ +
+ + +
+ + + + \ No newline at end of file diff --git a/public/session_02.html b/public/session_02.html new file mode 100644 index 00000000..da0aba6d --- /dev/null +++ b/public/session_02.html @@ -0,0 +1,717 @@ + + + + + + + + + +NCEAS Open Science Synthesis for the Delta Science Program - 2  Social Aspects of Collaboration + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

2  Social Aspects of Collaboration

+
+
+ + +
+ + + + +
+ + +
+ + +
+ + + +
+ + + + +
+

2.1 Developing a Code of Conduct

+

Whether you are joining a lab group or establishing a new collaboration, articulating a set of shared agreements about how people in the group will treat each other will help create the conditions for successful collaboration. If agreements or a code of conduct do not yet exist, invite a conversation among all members to create them. Co-creation of a code of conduct will foster collaboration and engagement as a process in and of itself, and is important to ensure all voices heard such that your code of conduct represents the perspectives of your community. If a code of conduct already exists, and your community will be a long-acting collaboration, you might consider revising the code of conduct. Having your group ‘sign off’ on the code of conduct, whether revised or not, supports adoption of the principles.

+

When creating a code of conduct, consider both the behaviors you want to encourage and those that will not be tolerated. For example, the Openscapes code of conduct includes Be respectful, honest, inclusive, accommodating, appreciative, and open to learning from everyone else. Do not attack, demean, disrupt, harass, or threaten others or encourage such behavior.

+

Below are other example codes of conduct:

+ +
+
+

2.2 Authorship and Credit Policies

+

+

Navigating issues of intellectual property and credit can be a challenge, particularly for early career researchers. Open communication is critical to avoiding misunderstandings and conflicts. Talk to your coauthors and collaborators about authorship, credit, and data sharing early and often. This is particularly important when working with new collaborators and across lab groups or disciplines which may have divergent views on authorship and data sharing. If you feel uncomfortable talking about issues surrounding credit or intellectual property, seek the advice or assistance of a mentor to support you in having these important conversations.

+

The “Publication” section of the Ecological Society of America’s Code of Ethics is a useful starting point for discussions about co-authorship, as are the International Committee of Medical Journal Editors guidelines for authorship and contribution. You should also check guidelines published by the journal(s) to which you anticipate submitting your work.

+

For collaborative research projects, develop an authorship agreement for your group early in the project and refer to it for each product. This example authorship agreement from the Arctic Data Center provides a useful template. It builds from information contained within Weltzin et al (2006) and provides a rubric for inclusion of individuals as authors. Your collaborative team may not choose to adopt the agreement in the current form, however it will prompt thought and discussion in advance of developing a consensus. Some key questions to consider as you are working with your team to develop the agreement:

+
    +
  • What roles do we anticipate contributors will play? e.g., the NISO Contributor Roles Taxonomy (CRediT) identifies 14 distinct roles:

    +
      +
    • Conceptualization
    • +
    • Data curation
    • +
    • Formal Analysis
    • +
    • Funding acquisition
    • +
    • Investigation
    • +
    • Methodology
    • +
    • Project administration
    • +
    • Resources
    • +
    • Software
    • +
    • Supervision
    • +
    • Validation
    • +
    • Visualization
    • +
    • Writing – original draft
    • +
    • Writing – review & editing
    • +
  • +
  • What are our criteria for authorship? (See the ICMJE guidelines for potential criteria)

  • +
  • Will we extend the opportunity for authorship to all group members on every paper or product?

  • +
  • Do we want to have an opt in or opt out policy? (In an opt out policy, all group members are considered authors from the outset and must request removal from the paper if they don’t want think they meet the criteria for authorship)

  • +
  • Who has the authority to make decisions about authorship? Lead author? PI? Group?

  • +
  • How will we decide authorship order?

  • +
  • In what other ways will we acknowledge contributions and extend credit to collaborators?

  • +
  • How will we resolve conflicts if they arise?

  • +
+
+
+

2.3 Data Sharing and Reuse Policies

+

As with authorship agreements, it is valuable to establish a shared agreement around handling of data when embarking on collaborative projects. Data collected as part of a funded research activity will typically have been managed as part of the Data Management Plan (DMP) associated with that project. However, collaborative research brings together data from across research projects with different data management plans and can include publicly accessible data from repositories where no management plan is available. For these reasons, a discussion and agreement around the handling of data brought into and resulting from the collaboration is warranted and management of this new data may benefit from going through a data management planning process. Below we discuss example data agreements.

+

The example data policy template provided by the Arctic Data Center addresses three categories of data.

+
    +
  • Individual data not in the public domain
  • +
  • Individual data with public access
  • +
  • Derived data resulting from the project
  • +
+

For the first category, the agreement considers conditions under which those data may be used and permissions associated with use. It also addresses access and sharing. In the case of individual, publicly accessible data, the agreement stipulates that the team will abide by the attribution and usage policies that the data were published under, noting how those requirements we met. In the case of derived data, the agreement reads similar to a DMP with consideration of making the data public; management, documentation and archiving; pre-publication sharing; and public sharing and attribution. As research data objects receive a persistent identifier (PID), often a DOI, there are citable objects and consideration should be given to authorship of data, as with articles.

+

The following example lab policy from the Wolkovich Lab combines data management practices with authorship guidelines and data sharing agreements. It provides a lot of detail about how this lab approaches data use, attribution and authorship. For example:

+
+

Section 6: Co-authorship & data

+

If you agree to take on existing data you cannot offer co-authorship for use of the data unless four criteria are met:

+
    +
  • The co-author agrees to (and does) make substantial intellectual contribution to the work, which includes the reading and editing of all manuscripts on which you are a co-author through the submission-for-publication stage. This includes helping with interpretation of the data, system, study questions.
  • +
  • Agreement of co-authorship is made at the start of the project.
  • +
  • Agreement is approved of by Lizzie.
  • +
  • All data-sharers are given an equal opportunity at authorship. It is not allowed to offer or give authorship to one data-sharer unless all other data-sharers are offered an equal opportunity at authorship—this includes data that are publicly-available, meaning if you offer authorship to one data-sharer and were planning to use publicly-available data you must reach out to the owner of the publicly-available data and strongly offer equivalent authorship as offered to the other data-sharer. As an example, if five people share data freely with you for a meta-analysis and and a sixth wants authorship you either must strongly offer equivalent authorship to all five or deny authorship to the sixth person. Note that the above requirements must also be met in this situation. If one or more datasets are more central or critical to a paper to warrant selective authorship this must be discussed and approved by Lizzie (and has not, to date, occurred within the lab).
  • +
+
+
+

+
+
+

2.3.0.1 Policy Preview

+ +

This policy is communicated with all incoming lab members, from undergraduate to postdocs and visiting scholars, and is shared here with permission from Dr Elizabeth Wolkovich.

+
+
+

2.3.1 Community Principles: CARE and FAIR

+

The CARE and FAIR Principles were introduced previously in the context of introducing the Arctic Data Center and our data submission and documentation process. In this section we will dive a little deeper.

+

To recap, the Arctic Data Center is an openly-accessible data repository and the data published through the repository is open for anyone to reuse, subject to conditions of the license (at the Arctic Data Center, data is released under one of two licenses: CC-0 Public Domain and CC-By Attribution 4.0). In facilitating use of data resources, the data stewardship community have converged on principles surrounding best practices for open data management One set of these principles is the FAIR principles. FAIR stands for Findable, Accessible, Interoperable, and Reproducible.

+

+

The “Fostering FAIR Data Practices in Europe” project found that it is more monetarily and timely expensive when FAIR principles are not used, and it was estimated that 10.2 billion dollars per years are spent through “storage and license costs to more qualitative costs related to the time spent by researchers on creation, collection and management of data, and the risks of research duplication.” FAIR principles and open science are overlapping concepts, but are distinctive concepts. Open science supports a culture of sharing research outputs and data, and FAIR focuses on how to prepare the data.

+

+

Another set of community developed principles surrounding open data are the CARE Principles. The CARE principles for Indigenous Data Governance complement the more data-centric approach of the FAIR principles, introducing social responsibility to open data management practices. The CARE Principles stand for:

+
    +
  • Collective Benefit - Data ecosystems shall be designed and function in ways that enable Indigenous Peoples to derive benefit from the data
  • +
  • Authority to Control - Indigenous Peoples’ rights and interests in Indigenous data must be recognised and their authority to control such data be empowered. Indigenous data governance enables Indigenous Peoples and governing bodies to determine how Indigenous Peoples, as well as Indigenous lands, territories, resources, knowledges and geographical indicators, are represented and identified within data.
  • +
  • Responsibility - Those working with Indigenous data have a responsibility to share how those data are used to support Indigenous Peoples’ self-determination and collective benefit. Accountability requires meaningful and openly available evidence of these efforts and the benefits accruing to Indigenous Peoples.
  • +
  • Ethics - Indigenous Peoples’ rights and wellbeing should be the primary concern at all stages of the data life cycle and across the data ecosystem.
  • +
+

The CARE principles align with the FAIR principles by outlining guidelines for publishing data that is findable, accessible, interoperable, and reproducible while at the same time, accounts for Indigenous’ Peoples rights and interests. Initially designed to support Indigenous data sovereignty, CARE principles are now being adopted across domains, and many researchers argue they are relevant for both Indigenous Knowledge and data, as well as data from all disciplines (Carroll et al., 2021). These principles introduce a “game changing perspective” that encourages transparency in data ethics, and encourages data reuse that is purposeful and intentional that aligns with human well-being aligns with human well-being (Carroll et al., 2021).

+
+
+
+

2.4 Research Data Publishing Ethics

+

For over 20 years, the Committee on Publication Ethics (COPE) has provided trusted guidance on ethical practices for scholarly publishing. The COPE guidelines have been broadly adopted by academic publishers across disciplines, and represent a common approach to identify, classify, and adjudicate potential breaches of ethics in publication such as authorship conflicts, peer review manipulation, and falsified findings, among many other areas. Despite these guidelines, there has been a lack of ethics standards, guidelines, or recommendations for data publications, even while some groups have begun to evaluate and act upon reported issues in data publication ethics.

+
+
+

+
Data retractions
+
+
+

To address this gap, the Force 11 Working Group on Research Data Publishing Ethics was formed as a collaboration among research data professionals and the Committee on Publication Ethics (COPE) “to develop industry-leading guidance and recommended best practices to support repositories, journal publishers, and institutions in handling the ethical responsibilities associated with publishing research data.” The group released the “Joint FORCE11 & COPE Research Data Publishing Ethics Working Group Recommendations” (Puebla, Lowenberg, and WG 2021), which outlines recommendations for four categories of potential data ethics issues:

+
+
+

+
Force11/COPE
+
+
+
    +
  • Authorship and Contribution Conflicts +
      +
    • Authorship omissions
    • +
    • Authorship ordering changes / conflicts
    • +
    • Institutional investigation of author finds misconduct
    • +
  • +
  • Legal/regulatory restrictions +
      +
    • Copyright violation
    • +
    • Insufficient rights for deposit
    • +
    • Breaches of national privacy laws (GPDR, CCPA)
    • +
    • Breaches of biosafety and biosecurity protocols
    • +
    • Breaches of contract law governing data redistribution
    • +
  • +
  • Risks of publication or release +
      +
    • Risks to human subjects +
        +
      • Lack of consent
      • +
      • Breaches of himan rights
      • +
      • Release of personally identifiable information (PII)
      • +
    • +
    • Risks to species, ecosystems, historical sites +
        +
      • Locations of endangered species or historical sites
      • +
    • +
    • Risks to communities or societies +
        +
      • Data harvested for profit or surveillance
      • +
      • Breaches of data sovereignty
      • +
    • +
  • +
  • Rigor of published data +
      +
    • Unintentional errors in collection, calculation, display
    • +
    • Un-interpretable data due to lack of adequate documentation
    • +
    • Errors of of study design and inference
    • +
    • Data manipulation or fabrication
    • +
  • +
+

Guidelines cover what actions need to be taken, depending on whether the data are already published or not, as well as who should be involved in decisions, who should be notified of actions, and when the public should be notified. The group has also published templates for use by publishers and repositories to announce the extent to which they plan to conform to the data ethics guidelines.

+
+

Discussion: Data publishing policies

+

At the Arctic Data Center, we need to develop policies and procedures governing how we react to potential breaches of data publication ethics. In this exercise, break into groups to provide advice on how the Arctic Data Center should respond to reports of data ethics issues, and whether we should adopt the Joint FORCE11 & COPE Research Data Publishing Ethics Working Group Policy Templates for repositories. In your discussion, consider:

+
    +
  • Should the repository adopt the repository policy templates from Force11?
  • +
  • Who should be involved in evaluation of the merits of ethical cases reported to ADC?
  • +
  • Who should be involved in deciding the actions to take?
  • +
  • What are the range of responses that the repository should consider for ethical breaches?
  • +
  • Who should be notified when a determination has been made that a breach has occurred?
  • +
+

You might consider a hypothetical scenario such as the following in considering your response.

+
+

The data coordinator at the Arctic Data Center receives an email in 2022 from a prior postdoctoral fellow who was employed as part of an NSF-funded project on microbial diversity in Alaskan tundra ecosystems. The email states that a dataset from 2014 in the Arctic Data Center was published with the project PI as author, but omits two people, the postdoc and an undergraduate student, as co-authors on the dataset. The PI retired in 2019, and the postdoc asks that they be added to the author list of the dataset to correct the historical record and provide credit.

+
+
+
+

+
+
+
+

2.5 Extra Reading

+ + + +
+
+Puebla, Iratxe, Daniella Lowenberg, and FORCE11 Research Data Publishing Ethics WG. 2021. Joint FORCE11 & COPE Research Data Publishing Ethics Working Group Recommendations.” Zenodo. https://doi.org/10.5281/zenodo.5391293. +
+
+
+ +
+ + +
+ + + + \ No newline at end of file diff --git a/public/session_03.html b/public/session_03.html new file mode 100644 index 00000000..7bb11eb8 --- /dev/null +++ b/public/session_03.html @@ -0,0 +1,500 @@ + + + + + + + + + +NCEAS Open Science Synthesis for the Delta Science Program - 3  Thinking Preferences + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

3  Thinking Preferences

+
+
+ + +
+ + + + +
+ + +
+ + +
+ + + +
+ + + + +

INSERT ONE OF THE THIKING PREFERENCES VERSIONS

+ + + +
+ + +
+ + + + \ No newline at end of file diff --git a/public/session_04.html b/public/session_04.html new file mode 100644 index 00000000..eef2681f --- /dev/null +++ b/public/session_04.html @@ -0,0 +1,500 @@ + + + + + + + + + +NCEAS Open Science Synthesis for the Delta Science Program - 4  Synthesis Time + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

4  Synthesis Time

+
+
+ + +
+ + + + +
+ + +
+ + +
+ + + +
+ + + + + + + + +
+ + +
+ + + + \ No newline at end of file diff --git a/public/session_05.html b/public/session_05.html new file mode 100644 index 00000000..0b3f8adf --- /dev/null +++ b/public/session_05.html @@ -0,0 +1,638 @@ + + + + + + + + + +NCEAS Open Science Synthesis for the Delta Science Program - 5  Publishing your Analysis to the Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

5  Publishing your Analysis to the Web

+
+
+ + +
+ + + + +
+ + +
+ + +
+ + + +
+ + + + +
+

Learning Objectives

+
    +
  • How to use Git, GitHub (+Pages), and R Markdown to publish an analysis to the web
  • +
+
+
+

5.1 Introduction

+

Sharing your work with others in engaging ways is an important part of the scientific process.

+

So far in this course, we’ve introduced a small set of powerful tools for doing open science:

+
    +
  • R and its many packages
  • +
  • RStudio
  • +
  • Git
  • +
  • GitHub
  • +
  • R Markdown
  • +
+

R Markdown, in particular, is amazingly powerful for creating scientific reports but, so far, we haven’t tapped its full potential for sharing our work with others.

+

In this lesson, we’re going to take our training_{USERNAME} GitHub repository and turn it into a beautiful and easy to read web page using the tools listed above.

+
+
+
+ +
+
+Set up +
+
+
+
    +
  1. Make sure you are in training_{USERNAME} project

  2. +
  3. Add a new R Markdown file at the top level called index.Rmd

    +
      +
    1. Go to the RStudio menu File > New File > R Markdown
    2. +
    3. This will bring up a dialog box. Add the title “GitHub Pages Example”, keep the Default Output Format as “HTML”, and then click “OK”
    4. +
  4. +
  5. Save the R Markdown file you just created. Use index.Rmd as the file name

    +
      +
    1. Be sure to use the exact case (lower case ‘index’) as different operating systems handle case differently and it can interfere with loading your web page later
    2. +
  6. +
  7. Press “Knit” and observe the rendered output

    +
      +
    1. Notice the new file in the same directory index.html
    2. +
    3. This is our R Markdown file rendered as HTML (a web page)
    4. +
  8. +
  9. Commit your changes (for both index.Rmd and index.html) with a commit message, and push to GitHub

  10. +
  11. Open your web browser to the GitHub.com and navigate to the page for your training_{USERNAME} repository

  12. +
  13. Activate GitHub Pages for the main branch

    +
      +
    1. Go to Settings > Pages (underneath the Code and Automation section)
    2. +
    3. Keep the “Source” as “Deploy from a branch”
    4. +
    5. Under “Branch” you’ll see a message that says “GitHub Pages is currently disabled”. To change this, change the branch from “None” to main. Keep the folder as the root and then click “Save”
    6. +
    7. You should see the message change to “Your GitHub Pages site is currently being built from the main branch”
    8. +
  14. +
+

Note: index.Rmd represents the default file for a web site, and is returned whenever you visit the web site but doesn’t specify an explicit file to be returned.

+
+
+

Now, the rendered website version of your repo will show up at a special URL.

+

GitHub Pages follows a convention like this:

+

GitHub Pages URL pattern

+

Note that it changes from github.com to github.io

+
    +
  • Go to https://{username}.github.io/{repo_name}/ (Note the trailing /)
  • +
  • Observe the awesome rendered output
  • +
+

Now that we’ve successfully published a web page from an R Markdown document, let’s make a change to our R Markdown document and follow the steps to publish the change on the web:

+
+
+
+ +
+
+Update content in your published page +
+
+
+
    +
  • Go back to your index.Rmd
  • +
  • Delete all the content, except the YAML frontmatter
  • +
  • Type “Hello world”
  • +
  • Use Git workflow: Stage > Commit > Pull > Push
  • +
  • Go back to https://{username}.github.io/{repo_name}/
  • +
+
+
+

Next, we will show how you can link different Rmds rendered into html so you can easily share different parts of your work.

+
+
+
+ +
+
+Exercise +
+
+
+

In this exercise, you’ll create a table of contents with the lessons of this course on the main page, and link some of the files we have work on so far.

+
    +
  • Go back to the RStudio server and to your index.Rmd file
  • +
  • Create a table of contents with the names of the main technical lessons of this course, like so:
  • +
+
## coreR workshop
+
+- Introduction to RMarkdown 
+- Cleaning and Wrangling data
+- Data Visualization
+- Spatial Analysis
+
    +
  • Make sure you have the html versions of your intro-to-rmd.Rmd and data-cleaning.Rmd files. If you only see the Rmd version, you need to “Knit” your files first

  • +
  • In your index.Rmd let’s add the links to the html files we want to show on our webpage. Do you remember the Markdown syntax to create a link?

  • +
+
+ +Markdown syntax to create a link: + +
    +
  • [Text you want to hyperlink](link) +
      +
    • Example: [Data wrangling and cleaning](data-wrangling-cleaning.html)
    • +
  • +
+
+
    +
  • Use Git workflow: Stage > Commit > Pull > Push
  • +
+

Now when you visit your web site, you’ll see the table of contents, and can navigate to the others file you linked.

+
+
+

R Markdown web pages are a great way to share work in progress with your colleagues. Here we showed an example with the materials we have created in this course. However, you can use these same steps to share the different files and progress of a project you’ve been working on. To do so simply requires thinking through your presentation so that it highlights the workflow to be reviewed. You can include multiple pages and build a simple web site and make your work accessible to people who aren’t set up to open your project in R. Your site could look something like this:

+

+ + +
+ +
+ + +
+ + + + \ No newline at end of file diff --git a/public/session_06.html b/public/session_06.html new file mode 100644 index 00000000..4591770f --- /dev/null +++ b/public/session_06.html @@ -0,0 +1,1221 @@ + + + + + + + + + +NCEAS Open Science Synthesis for the Delta Science Program - 6  Data Visualization in R + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

6  Data Visualization in R

+
+
+ + +
+ + + + +
+ + +
+ + +
+ + + +
+ + + + +
+

Learning Objectives

+
    +
  • The basics of the ggplot2 package to create static plots
  • +
  • How to use ggplot2’s theme abilities to create publication-grade graphics
  • +
  • The basics of the leaflet package to create interactive maps
  • +
+
+
+

6.1 Overview

+

ggplot2 is a popular package for visualizing data in R. From the home page:

+
+

ggplot2 is a system for declaratively creating graphics, based on The Grammar of Graphics. You provide the data, tell ggplot2 how to map variables to aesthetics, what graphical primitives to use, and it takes care of the details.

+
+

It’s been around for years and has pretty good documentation and tons of example code around the web (like on StackOverflow). The goal of this lesson is to introduce you to the basic components of working with ggplot2 and inspire you to go and explore this awesome resource for visualizing your data.

+
+
+
+ +
+
+ggplot2 vs base graphics in R vs others +
+
+
+

There are many different ways to plot your data in R. All of them work! However, ggplot2 excels at making complicated plots easy and easy plots simple enough

+

Base R graphics (plot(), hist(), etc) can be helpful for simple, quick and dirty plots. ggplot2 can be used for almost everything else.

+
+
+

Let’s dive into creating and customizing plots with ggplot2.

+
+
+
+ +
+
+Setup +
+
+
+
    +
  1. Make sure you’re in the right project (training_{USERNAME}) and use the Git workflow by Pulling to check for any changes. Then, create a new R Markdown document and remove the default text.

  2. +
  3. Load the packages we’ll need:

  4. +
+
+
library(readr)
+library(dplyr)
+library(tidyr)
+library(forcats)
+library(ggplot2)
+library(leaflet)
+library(DT)
+library(scales)
+
+
    +
  1. Load the data table directly from the KNB Data Repository: Daily salmon escapement counts from the OceanAK database, Alaska, 1921-2017. Navegate to the link above, hover over the “Download” button for the ADFG_fisrtAttempt_reformatted.csv, right click, and select “Copy Link”.
  2. +
+
+
escape <- read_csv("https://knb.ecoinformatics.org/knb/d1/mn/v2/object/urn%3Auuid%3Af119a05b-bbe7-4aea-93c6-85434dcb1c5e")
+
+
    +
  1. Learn about the data. For this session we are going to be working with data on daily salmon escapement counts in Alaska. Check out the documentation.

  2. +
  3. Finally, let’s explore the data we just read into our working environment.

  4. +
+
+
## Check out column names
+colnames(escape)
+
+## Peak at each column and class
+glimpse(escape)
+
+## From when to when
+range(escape$sampleDate)
+
+## How frequent?
+head(escape$sampleDate)
+tail(escape$sampleDate)
+
+## Which species?
+unique(escape$Species)
+
+
+
+
+
+

6.2 Getting the data ready

+

It is more frequent than not, that we need to do some wrangling before we can plot our data the way we want to. Now that we have read out data and have done some exploration, we’ll put our data wrangling skills to practice to get our data in the desired format.

+
+
+
+ +
+
+Exercise +
+
+
+
    +
  • Calculate the annual escapement by Species and SASAP.Region,
  • +
  • Filter the main 5 salmon species (Chinook, Sockeye, Chum, Coho and Pink)
  • +
+
+
+
+
annual_esc <- escape %>%
+    separate(sampleDate, c("Year", "Month", "Day"), sep = "-") %>%
+    mutate(Year = as.numeric(Year)) %>%
+    group_by(Species, SASAP.Region, Year) %>%
+    summarize(escapement = sum(DailyCount)) %>%
+    filter(Species %in% c("Chinook", "Sockeye", "Chum", "Coho", "Pink"))
+
+head(annual_esc)
+
+
# A tibble: 6 × 4
+# Groups:   Species, SASAP.Region [1]
+  Species SASAP.Region                           Year escapement
+  <chr>   <chr>                                 <dbl>      <dbl>
+1 Chinook Alaska Peninsula and Aleutian Islands  1974       1092
+2 Chinook Alaska Peninsula and Aleutian Islands  1975       1917
+3 Chinook Alaska Peninsula and Aleutian Islands  1976       3045
+4 Chinook Alaska Peninsula and Aleutian Islands  1977       4844
+5 Chinook Alaska Peninsula and Aleutian Islands  1978       3901
+6 Chinook Alaska Peninsula and Aleutian Islands  1979      10463
+
+
+

The chunk above used a lot of the dplyr commands that we’ve used, and some that are new. The separate() function is used to divide the sampleDate column up into Year, Month, and Day columns, and then we use group_by() to indicate that we want to calculate our results for the unique combinations of species, region, and year. We next use summarize() to calculate an escapement value for each of these groups. Finally, we use a filter and the %in% operator to select only the salmon species.

+
+
+

6.3 Plotting with ggplot2

+
+

6.3.1 Essentials components

+

First, we’ll cover some ggplot2 basics to create the foundation of our plot. Then, we’ll add on to make our great customized data visualization.

+
+
+
+ +
+
+The basics +
+
+
+
    +
  1. Indicate we are using ggplot() (call the ggplot2::ggplot() function)
  2. +
  3. What data do we want to plot? (data = my_data)
  4. +
  5. What is my mapping aesthetics? What variables do we want to plot? (define usingaes() function)
  6. +
  7. Define the geometry of our plot. This specifies the type of plot we’re making (use geom_*() to indicate the type of plot e.g: point, bar, etc.)
  8. +
+

Note To add layers to our plot, for example, additional geometries/aesthetics and theme elements or any ggplot object we use +.

+
+
+

For example, let’s plot total escapement by species. We will show this by creating the same plot in 3 slightly different ways. Each of the options below have the essential pieces of a ggplot.

+
+
## Option 1 - data and mapping called in the ggplot() function
+ggplot(data = annual_esc,
+       aes(x = Species, y = escapement)) +
+    geom_col()
+
+## Option 2 - data called in ggplot function; mapping called in geom
+ggplot(data = annual_esc) +
+    geom_col(aes(x = Species, y = escapement))
+
+
+## Option 3 - data and mapping called in geom
+ggplot() +
+    geom_col(data = annual_esc,
+             aes(x = Species, y = escapement))
+
+

They all will create the same plot:

+
+
+

+
+
+
+
+

6.3.2 Looking at different geoms

+

Having the basic structure with the essential components in mind, we can easily change the type of graph by updating the geom_*().

+
+
+
+ +
+
+ggplot2 and the pipe operator +
+
+
+

Just like in dplyr and tidyr, we can also pipe a data.frame directly into the first argument of the ggplot function using the %>% operator.

+

This can certainly be convenient, but use it carefully! Combining too many data-tidying or subsetting operations with your ggplot call can make your code more difficult to debug and understand.

+
+
+

Next, we will use the pipe operator to pass into ggplot() a filtered version of annual_esc, and make a plot with different geometries.

+

Boxplot

+
+
annual_esc %>%
+    filter(Year == 1974,
+           Species %in% c("Chum", "Pink")) %>%
+    ggplot(aes(x = Species, y = escapement)) +
+    geom_boxplot()
+
+

+
+
+

Violin plot

+
+
annual_esc %>%
+    filter(Year == 1974,
+           Species %in% c("Chum", "Pink")) %>%
+    ggplot(aes(x = Species, y = escapement)) +
+    geom_violin()
+
+

+
+
+

Line and point

+
+
annual_esc %>%
+    filter(Species  == "Sockeye",
+           SASAP.Region == "Bristol Bay") %>%
+    ggplot(aes(x = Year, y = escapement)) +
+    geom_line() +
+    geom_point()
+
+

+
+
+
+
+

6.3.3 Customizing our plot

+

Let’s go back to our base bar graph. What if we want our bars to be blue instead of gray? You might think we could run this:

+
+
ggplot(annual_esc,
+       aes(x = Species, y = escapement,
+           fill = "blue")) +
+    geom_col()
+
+

+
+
+

Why did that happen?

+

Notice that we tried to set the fill color of the plot inside the mapping aesthetic call. What we have done, behind the scenes, is create a column filled with the word “blue” in our data frame, and then mapped it to the fill aesthetic, which then chose the default fill color of red.

+

What we really wanted to do was just change the color of the bars. If we want do do that, we can call the color option in the geom_col() function, outside of the mapping aesthetics function call.

+
+
ggplot(annual_esc,
+       aes(x = Species, y = escapement)) +
+    geom_col(fill = "blue")
+
+

+
+
+

What if we did want to map the color of the bars to a variable, such as region. ggplot() is really powerful because we can easily get this plot to visualize more aspects of our data.

+
+
ggplot(annual_esc,
+       aes(x = Species, y = escapement,
+           fill = SASAP.Region)) +
+    geom_col()
+
+

+
+
+
+
+
+ +
+
+Keep in mind +
+
+
+
    +
  • If you want to map a variable onto a graph aesthetic (e.g., point color should be based on a specific region), put it within aes().

  • +
  • If you want to update your plot base on a constant (e.g. “Make ALL the points BLUE”), you can add the information directly to the relevant geom_ layer.

  • +
+
+
+
+

6.3.3.1 Creating multiple plots

+

We know that in the graph we just plotted, each bar includes escapements for multiple years. Let’s leverage the power of ggplot to plot more aspects of our data in one plot.

+

We are going to plot escapement by species over time, from 2000 to 2016, for each region.

+

An easy way to plot another aspect of your data is using the function facet_wrap(). This function takes a mapping to a variable using the syntax ~{variable_name}. The ~ (tilde) is a model operator which tells facet_wrap() to model each unique value within variable_name to a facet in the plot.

+

The default behavior of facet wrap is to put all facets on the same x and y scale. You can use the scales argument to specify whether to allow different scales between facet plots (e.g scales = "free_y" to free the y axis scale). You can also specify the number of columns using the ncol = argument or number of rows using nrow =.

+
+
## Subset with data from years 2000 to 2016
+
+annual_esc_2000s <- annual_esc %>%
+    filter(Year %in% c(2000:2016))
+
+## Quick check
+unique(annual_esc_2000s$Year)
+
+
 [1] 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014
+[16] 2015 2016
+
+
## Plot with facets
+ggplot(annual_esc_2000s,
+       aes(x = Year,
+           y = escapement,
+           color = Species)) +
+    geom_line() +
+    geom_point() +
+    facet_wrap( ~ SASAP.Region,
+                scales = "free_y")
+
+

+
+
+
+
+

6.3.3.2 Setting ggplot themes

+

Now let’s work on making this plot look a bit nicer. We are going to”

+
    +
  • Add a title using ggtitle()
  • +
  • Adjust labels using ylab()
  • +
  • Include a built in theme using theme_bw()
  • +
+

There are a wide variety of built in themes in ggplot that help quickly set the look of the plot. Use the RStudio autocomplete theme_ <TAB> to view a list of theme functions.

+
+
ggplot(annual_esc_2000s,
+       aes(x = Year,
+           y = escapement,
+           color = Species)) +
+    geom_line() +
+    geom_point() +
+    facet_wrap( ~ SASAP.Region,
+                scales = "free_y") +
+    ylab("Escapement") +
+    ggtitle("Annual Salmon Escapement by Region") +
+    theme_bw()
+
+

+
+
+

You can see that the theme_bw() function changed a lot of the aspects of our plot! The background is white, the grid is a different color, etc. There are lots of other built in themes like this that come with the ggplot2 package.

+
+
+
+ +
+
+Exercise +
+
+
+

Use the RStudio auto complete, the ggplot2 documentation, a cheat sheet, or good old Google to find other built in themes. Pick out your favorite one and add it to your plot.

+
+
+
+
+Themes +
## Useful baseline themes are
+theme_minimal()
+theme_light()
+theme_classic()
+
+
+

The built in theme functions (theme_*()) change the default settings for many elements that can also be changed individually using thetheme() function. The theme() function is a way to further fine-tune the look of your plot. This function takes MANY arguments (just have a look at ?theme). Luckily there are many great ggplot resources online so we don’t have to remember all of these, just Google “ggplot cheat sheet” and find one you like.

+

Let’s look at an example of a theme() call, where we change the position of the legend from the right side to the bottom, and remove its title.

+
+
ggplot(annual_esc_2000s,
+       aes(x = Year,
+           y = escapement,
+           color = Species)) +
+    geom_line() +
+    geom_point() +
+    facet_wrap( ~ SASAP.Region,
+                scales = "free_y") +
+    ylab("Escapement") +
+    ggtitle("Annual Salmon Escapement by Region") +
+    theme_light() +
+    theme(legend.position = "bottom",
+          legend.title = element_blank())
+
+

+
+
+

Note that the theme() call needs to come after any built-in themes like theme_bw() are used. Otherwise, theme_bw() will likely override any theme elements that you changed using theme().

+

You can also save the result of a series of theme() function calls to an object to use on multiple plots. This prevents needing to copy paste the same lines over and over again!

+
+
my_theme <- theme_light() +
+    theme(legend.position = "bottom",
+          legend.title = element_blank())
+
+

So now our code will look like this:

+
+
ggplot(annual_esc_2000s,
+       aes(x = Year,
+           y = escapement,
+           color = Species)) +
+    geom_line() +
+    geom_point() +
+    facet_wrap( ~ SASAP.Region,
+                scales = "free_y") +
+    ylab("Escapement") +
+    ggtitle("Annual Salmon Escapement by Region") +
+    my_theme
+
+

+
+
+
+
+
+ +
+
+Exercise +
+
+
+
    +
  1. Using whatever method you like, figure out how to rotate the x-axis tick labels to a 45 degree angle.
  2. +
+

Hint: You can start by looking at the documentation of the function by typing ?theme() in the console. And googling is a great way to figure out how to do the modifications you want to your plot.

+
    +
  1. What changes do you expect to see in your plot by adding the following line of code? Discuss with your neighbor and then try it out!
  2. +
+

scale_x_continuous(breaks = seq(2000,2016, 2))

+
+
+
+
+Answer +
## Useful baseline themes are
+ggplot(annual_esc_2000s,
+       aes(x = Year,
+           y = escapement,
+           color = Species)) +
+    geom_line() +
+    geom_point() +
+    scale_x_continuous(breaks = seq(2000, 2016, 2)) +
+    facet_wrap( ~ SASAP.Region,
+                scales = "free_y") +
+    ylab("Escapement") +
+    ggtitle("Annual Salmon Escapement by Region") +
+    my_theme +
+    theme(axis.text.x = element_text(angle = 45,
+                                     vjust = 0.5))
+
+
+
+
+

6.3.3.3 Smarter tick labels using scales

+

Fixing tick labels in ggplot can be super annoying. The y-axis labels in the plot above don’t look great. We could manually fix them, but it would likely be tedious and error prone.

+

The scales package provides some nice helper functions to easily rescale and relabel your plots. Here, we use scale_y_continuous() from ggplot2, with the argument labels, which is assigned to the function name comma, from the scales package. This will format all of the labels on the y-axis of our plot with comma-formatted numbers.

+
+
ggplot(annual_esc_2000s,
+       aes(x = Year,
+           y = escapement,
+           color = Species)) +
+    geom_line() +
+    geom_point() +
+    scale_x_continuous(breaks = seq(2000, 2016, 2)) +
+    scale_y_continuous(labels = comma) +
+    facet_wrap( ~ SASAP.Region,
+                scales = "free_y") +
+    ylab("Escapement") +
+    ggtitle("Annual Salmon Escapement by Region") +
+    my_theme +
+    theme(axis.text.x = element_text(angle = 45,
+                                     vjust = 0.5))
+
+

+
+
+

You can also save all your code into an object in your working environment by assigning a name to the ggplot() code.

+
+
annual_region_plot <- ggplot(annual_esc_2000s,
+                             aes(x = Year,
+                                 y = escapement,
+                                 color = Species)) +
+    geom_line() +
+    geom_point() +
+    scale_x_continuous(breaks = seq(2000, 2016, 2)) +
+    scale_y_continuous(labels = comma) +
+    facet_wrap( ~ SASAP.Region,
+                scales = "free_y") +
+    ylab("Escapement") +
+    xlab("\nYear") +
+    ggtitle("Annual Salmon Escapement by Region") +
+    my_theme +
+    theme(axis.text.x = element_text(angle = 45,
+                                     vjust = 0.5))
+
+

And then call your object to see your plot.

+
+
annual_region_plot
+
+

+
+
+
+
+

6.3.3.4 Reordering things

+

ggplot() loves putting things in alphabetical order. But more frequent than not, that’s not the order you actually want things to be plotted if you have categorical groups. Let’s find some total years of data by species for Kuskokwim.

+
+
## Number Years of data for each salmon species at Kuskokwim
+n_years <- annual_esc %>%
+    group_by(SASAP.Region, Species) %>%
+    summarize(n = n()) %>%
+    filter(SASAP.Region == "Kuskokwim")
+
+

Now let’s plot this using geom_bar().

+
+
## base plot
+ggplot(n_years,
+       aes(x = Species,
+           y = n)) +
+    geom_bar(aes(fill = Species),
+             stat = "identity")
+
+

+
+
+

Now, let’s apply some of the customizations we have seen so far and learn some new ones.

+
+
## Reordering, flipping coords and other customization
+ggplot(n_years,
+       aes(
+           x = fct_reorder(Species, n),
+           y = n,
+           fill = Species
+       )) +
+    geom_bar(stat = "identity") +
+    coord_flip() +
+    theme_minimal() +
+    ## another way to customize labels
+    labs(x = "Species",
+         y = "Number of years of data",
+         title = "Number of years of escapement data for salmon species in Kuskokwim") +
+    theme(legend.position = "none")
+
+

+
+
+
+
+

6.3.3.5 Saving plots

+

Saving plots using ggplot is easy! The ggsave() function will save either the last plot you created, or any plot that you have saved to a variable. You can specify what output format you want, size, resolution, etc. See ?ggsave() for documentation.

+
+
ggsave("figures/nyears_data_kus.jpg", width = 8, height = 6, units = "in")
+
+

We can also save our facet plot showing annual escapements by region calling the plot’s object.

+
+
ggsave(annual_region_plot, "figures/annual_esc_region.png", width = 12, height = 8, units = "in")
+
+
+
+
+
+

6.4 Interactive visualization

+
+

6.4.1 Tables with DT

+

Now that we know how to make great static visualizations, let’s introduce two other packages that allow us to display our data in interactive ways. These packages really shine when used with GitHub Pages, so at the end of this lesson we will publish our figures to the website we created earlier.

+

First let’s show an interactive table of unique sampling locations using DT. Write a data.frame containing unique sampling locations with no missing values using two new functions from dplyr and tidyr: distinct() and drop_na().

+
+
locations <- escape %>%
+    distinct(Location, Latitude, Longitude) %>%
+    drop_na()
+
+

And display it as an interactive table using datatable() from the DT package.

+
+
datatable(locations)
+
+ +
+ +
+
+
+
+

6.4.2 Maps with leaflet

+

Similar to ggplot2, you can make a basic leaflet map using just a couple lines of code. Note that unlike ggplot2, the leaflet package uses pipe operators (%>%) and not the additive operator (+).

+

The addTiles() function without arguments will add base tiles to your map from OpenStreetMap. addMarkers() will add a marker at each location specified by the latitude and longitude arguments. Note that the ~ symbol is used here to model the coordinates to the map (similar to facet_wrap() in ggplot).

+
+
leaflet(locations) %>%
+    addTiles() %>%
+    addMarkers(
+        lng = ~ Longitude,
+        lat = ~ Latitude,
+        popup = ~ Location
+    )
+
+
+ +
+
+


+

You can also use leaflet to import Web Map Service (WMS) tiles. Here is an example that utilizes the General Bathymetric Map of the Oceans (GEBCO) WMS tiles. In this example, we also demonstrate how to create a more simple circle marker, the look of which is explicitly set using a series of style-related arguments.

+
+
leaflet(locations) %>%
+    addWMSTiles(
+        "https://www.gebco.net/data_and_products/gebco_web_services/web_map_service/mapserv?request=getmap&service=wms&BBOX=-90,-180,90,360&crs=EPSG:4326&format=image/jpeg&layers=gebco_latest&width=1200&height=600&version=1.3.0",
+        layers = 'GEBCO_LATEST',
+        attribution = "Imagery reproduced from the GEBCO_2022 Grid, WMS 1.3.0 GetMap, www.gebco.net"
+    ) %>%
+    addCircleMarkers(
+        lng = ~ Longitude,
+        lat = ~ Latitude,
+        popup = ~ Location,
+        radius = 5,
+        # set fill properties
+        fillColor = "salmon",
+        fillOpacity = 1,
+        # set stroke properties
+        stroke = T,
+        weight = 0.5,
+        color = "white",
+        opacity = 1
+    )
+
+
+ +
+
+


+

Leaflet has a ton of functionality that can enable you to create some beautiful, functional maps with relative ease. Here is an example of some we created as part of the State of Alaskan Salmon and People (SASAP) project, created using the same tools we showed you here. This map hopefully gives you an idea of how powerful the combination of R Markdown and GitHub Pages can be.

+
+
+
+

6.5 Publish the Data Visualization lesson to your webpage

+
+
+
+ +
+
+Steps +
+
+
+
    +
  1. Save the Rmd you have been working on for this lesson.
  2. +
  3. “Knit” the Rmd. This is a good way to test if everything in your code is working.
  4. +
  5. Go to your index.Rmd and the link to the html file with this lesson’s content.
  6. +
  7. Save and render index.Rmd to an html.
  8. +
  9. Use the Git workflow: Stage > Commit > Pull > Push
  10. +
+
+
+
+
+

6.6 ggplot2 Resources

+ + + +
+ +
+ + +
+ + + + \ No newline at end of file diff --git a/public/session_06_files/figure-html/boxplot_ex-1.png b/public/session_06_files/figure-html/boxplot_ex-1.png new file mode 100644 index 00000000..96c507a3 Binary files /dev/null and b/public/session_06_files/figure-html/boxplot_ex-1.png differ diff --git a/public/session_06_files/figure-html/esc_plot-1.png b/public/session_06_files/figure-html/esc_plot-1.png new file mode 100644 index 00000000..7ac62aa3 Binary files /dev/null and b/public/session_06_files/figure-html/esc_plot-1.png differ diff --git a/public/session_06_files/figure-html/facet_base_plot-1.png b/public/session_06_files/figure-html/facet_base_plot-1.png new file mode 100644 index 00000000..9537f058 Binary files /dev/null and b/public/session_06_files/figure-html/facet_base_plot-1.png differ diff --git a/public/session_06_files/figure-html/fill_blue-1.png b/public/session_06_files/figure-html/fill_blue-1.png new file mode 100644 index 00000000..08398724 Binary files /dev/null and b/public/session_06_files/figure-html/fill_blue-1.png differ diff --git a/public/session_06_files/figure-html/fill_blue_geom-1.png b/public/session_06_files/figure-html/fill_blue_geom-1.png new file mode 100644 index 00000000..e9fc8f4f Binary files /dev/null and b/public/session_06_files/figure-html/fill_blue_geom-1.png differ diff --git a/public/session_06_files/figure-html/line_poin_plot-1.png b/public/session_06_files/figure-html/line_poin_plot-1.png new file mode 100644 index 00000000..d429cd1c Binary files /dev/null and b/public/session_06_files/figure-html/line_poin_plot-1.png differ diff --git a/public/session_06_files/figure-html/theme_bw_plot-1.png b/public/session_06_files/figure-html/theme_bw_plot-1.png new file mode 100644 index 00000000..f1c1e6d7 Binary files /dev/null and b/public/session_06_files/figure-html/theme_bw_plot-1.png differ diff --git a/public/session_06_files/figure-html/unnamed-chunk-10-1.png b/public/session_06_files/figure-html/unnamed-chunk-10-1.png new file mode 100644 index 00000000..8ea7694d Binary files /dev/null and b/public/session_06_files/figure-html/unnamed-chunk-10-1.png differ diff --git a/public/session_06_files/figure-html/unnamed-chunk-11-1.png b/public/session_06_files/figure-html/unnamed-chunk-11-1.png new file mode 100644 index 00000000..a2b0869d Binary files /dev/null and b/public/session_06_files/figure-html/unnamed-chunk-11-1.png differ diff --git a/public/session_06_files/figure-html/unnamed-chunk-12-1.png b/public/session_06_files/figure-html/unnamed-chunk-12-1.png new file mode 100644 index 00000000..c0da8ec1 Binary files /dev/null and b/public/session_06_files/figure-html/unnamed-chunk-12-1.png differ diff --git a/public/session_06_files/figure-html/unnamed-chunk-3-1.png b/public/session_06_files/figure-html/unnamed-chunk-3-1.png new file mode 100644 index 00000000..b4081e43 Binary files /dev/null and b/public/session_06_files/figure-html/unnamed-chunk-3-1.png differ diff --git a/public/session_06_files/figure-html/unnamed-chunk-5-1.png b/public/session_06_files/figure-html/unnamed-chunk-5-1.png new file mode 100644 index 00000000..14af3087 Binary files /dev/null and b/public/session_06_files/figure-html/unnamed-chunk-5-1.png differ diff --git a/public/session_06_files/figure-html/unnamed-chunk-6-1.png b/public/session_06_files/figure-html/unnamed-chunk-6-1.png new file mode 100644 index 00000000..14af3087 Binary files /dev/null and b/public/session_06_files/figure-html/unnamed-chunk-6-1.png differ diff --git a/public/session_06_files/figure-html/unnamed-chunk-8-1.png b/public/session_06_files/figure-html/unnamed-chunk-8-1.png new file mode 100644 index 00000000..de3d696d Binary files /dev/null and b/public/session_06_files/figure-html/unnamed-chunk-8-1.png differ diff --git a/public/session_06_files/figure-html/violin_plot-1.png b/public/session_06_files/figure-html/violin_plot-1.png new file mode 100644 index 00000000..74ae1c5a Binary files /dev/null and b/public/session_06_files/figure-html/violin_plot-1.png differ diff --git a/public/session_07.html b/public/session_07.html new file mode 100644 index 00000000..3ebb874b --- /dev/null +++ b/public/session_07.html @@ -0,0 +1,501 @@ + + + + + + + + + +NCEAS Open Science Synthesis for the Delta Science Program - 7  Systematic Reviews + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

7  Systematic Reviews

+
+
+ + +
+ + + + +
+ + +
+ + +
+ + + +
+ + + + + +

ADD LINK TO MATERIAL

+ + + +
+ + +
+ + + + \ No newline at end of file diff --git a/public/session_08.html b/public/session_08.html new file mode 100644 index 00000000..1a6f7e97 --- /dev/null +++ b/public/session_08.html @@ -0,0 +1,500 @@ + + + + + + + + + +NCEAS Open Science Synthesis for the Delta Science Program - 8  Synthesis Time + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

8  Synthesis Time

+
+
+ + +
+ + + + +
+ + +
+ + +
+ + + +
+ + + + + + + + +
+ + +
+ + + + \ No newline at end of file diff --git a/public/session_09.html b/public/session_09.html new file mode 100644 index 00000000..88f73c11 --- /dev/null +++ b/public/session_09.html @@ -0,0 +1,1349 @@ + + + + + + + + + +NCEAS Open Science Synthesis for the Delta Science Program - 9  Using sf for Spatia Data & Intro to Making Maps + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

9  Using sf for Spatia Data & Intro to Making Maps

+
+
+ + +
+ + + + +
+ + +
+ + +
+ + + +
+ + + + +
+

Learning Objectives

+
    +
  • How to use the sf package to wrangle spatial data
  • +
  • Static mapping with ggplot
  • +
  • Adding basemaps to static maps
  • +
  • Interactive mapping with leaflet
  • +
+
+
+

9.1 Brief introduction to sf

+

From the sf vignette:

+
+

Simple features or simple feature access refers to a formal standard (ISO 19125-1:2004) that describes how objects in the real world can be represented in computers, with emphasis on the spatial geometry of these objects. It also describes how such objects can be stored in and retrieved from databases, and which geometrical operations should be defined for them.

+
+

The sf package is an R implementation of Simple Features. This package incorporates:

+
    +
  • a new spatial data class system in R
    +
  • +
  • functions for reading and writing spatial data
    +
  • +
  • tools for spatial operations on vectors
  • +
+

Most of the functions in this package starts with prefix st_ which stands for spatial and temporal.

+

In this lesson, our goal is to use a shapefile of Alaska regions and rivers, and data on population in Alaska by community to create a map that looks like this:

+

+
+
+

9.2 About the data

+

All of the data used in this tutorial are simplified versions of real datasets available on the KNB Data Repository. We are using simplified datasets to ease the processing burden on all our computers since the original geospatial datasets are high-resolution. These simplified versions of the datasets may contain topological errors.

+

The spatial data we will be using to create the map are:

+ + + + + + + + + + + + + + + + + + + + + +
DataOriginal datasets
Alaska regional boundariesJared Kibele and Jeanette Clark. 2018. State of Alaska’s Salmon and People Regional Boundaries. Knowledge Network for Biocomplexity. doi:10.5063/F1125QWP.
Community locations and populationJeanette Clark, Sharis Ochs, Derek Strong, and National Historic Geographic Information System. 2018. Languages used in Alaskan households, 1990-2015. Knowledge Network for Biocomplexity. doi:10.5063/F11G0JHX.
Alaska riversThe rivers shapefile is a simplified version of Jared Kibele and Jeanette Clark. Rivers of Alaska grouped by SASAP region, 2018. Knowledge Network for Biocomplexity. doi:10.5063/F1SJ1HVW.
+
+
+
+ +
+
+Setup +
+
+
+
    +
  1. Navigate to this dataset on KNB’s test site and download the zip folder.
  2. +
  3. Upload the zip folder to the data folder in the training_{USERNAME} project. You don’t need to unzip the folder ahead of time, uploading will automatically unzip the folder.
  4. +
  5. Create a new R Markdown file. +
      +
    1. Title it “Intro to sf package for Spatial Data and Making Maps”
    2. +
    3. Save the file and name it “intro-sf-spatial-data-maps”.
    4. +
  6. +
  7. Load the following libraries at the top of your R Markdown file.
  8. +
+
+
library(readr)
+library(sf)
+library(ggplot2)
+library(leaflet)
+library(scales)
+library(ggmap)
+library(dplyr)
+
+
+
+
+
+

9.3 Exploring the data using plot() and st_crs()

+

First let’s read in the shapefile of regional boundaries in Alaska using read_sf() and then create a basic plot of the data plot().

+
+
# read in shapefile using read_sf()
+ak_regions <- read_sf("data/ak_regions_simp.shp")
+
+
+
# quick plot
+plot(ak_regions)
+
+

+
+
+

We can also examine it’s class using class().

+
+
class(ak_regions)
+
+
[1] "sf"         "tbl_df"     "tbl"        "data.frame"
+
+
+

sf objects usually have two types of classes: sf and data.frame.

+

Unlike a typical data.frame, an sf object has spatial metadata (geometry type, dimension, bbox, epsg (SRID), proj4string) and an additional column typically named geometry that contains the spatial data.

+

Since our shapefile object has the data.frame class, viewing the contents of the object using the head() function or other exploratory functions shows similar results as if we read in data using read.csv() or read_csv().

+
+
head(ak_regions)
+
+
Simple feature collection with 6 features and 3 fields
+Geometry type: MULTIPOLYGON
+Dimension:     XY
+Bounding box:  xmin: -179.2296 ymin: 51.15702 xmax: 179.8567 ymax: 71.43957
+Geodetic CRS:  WGS 84
+# A tibble: 6 × 4
+  region_id region           mgmt_area                                  geometry
+      <int> <chr>                <dbl>                        <MULTIPOLYGON [°]>
+1         1 Aleutian Islands         3 (((-171.1345 52.44974, -171.1686 52.4174…
+2         2 Arctic                   4 (((-139.9552 68.70597, -139.9893 68.7051…
+3         3 Bristol Bay              3 (((-159.8745 58.62778, -159.8654 58.6137…
+4         4 Chignik                  3 (((-155.8282 55.84638, -155.8049 55.8655…
+5         5 Copper River             2 (((-143.8874 59.93931, -143.9165 59.9403…
+6         6 Kodiak                   3 (((-151.9997 58.83077, -152.0358 58.8271…
+
+
glimpse(ak_regions)
+
+
Rows: 13
+Columns: 4
+$ region_id <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
+$ region    <chr> "Aleutian Islands", "Arctic", "Bristol Bay", "Chignik", "Cop…
+$ mgmt_area <dbl> 3, 4, 3, 3, 2, 3, 4, 4, 2, 4, 2, 1, 4
+$ geometry  <MULTIPOLYGON [°]> MULTIPOLYGON (((-171.1345 5..., MULTIPOLYGON (((-139.9552 6.…
+
+
+
+

9.3.1 Coordinate Reference System (CRS)

+
+
+

+
Source: ESRI
+
+
+

Every sf object needs a coordinate reference system (or crs) defined in order to work with it correctly. A coordinate reference system contains both a datum and a projection. The datum is how you georeference your points (in 3 dimensions!) onto a spheroid. The projection is how these points are mathematically transformed to represent the georeferenced point on a flat piece of paper. All coordinate reference systems require a datum. However, some coordinate reference systems are “unprojected” (also called geographic coordinate systems). Coordinates in latitude/longitude use a geographic (unprojected) coordinate system. One of the most commonly used geographic coordinate systems is WGS 1984.

+

ESRI has a blog post that explains these concepts in more detail with very helpful diagrams and examples.

+

You can view what crs is set by using the function st_crs().

+
+
st_crs(ak_regions)
+
+
Coordinate Reference System:
+  User input: WGS 84 
+  wkt:
+GEOGCRS["WGS 84",
+    DATUM["World Geodetic System 1984",
+        ELLIPSOID["WGS 84",6378137,298.257223563,
+            LENGTHUNIT["metre",1]]],
+    PRIMEM["Greenwich",0,
+        ANGLEUNIT["degree",0.0174532925199433]],
+    CS[ellipsoidal,2],
+        AXIS["latitude",north,
+            ORDER[1],
+            ANGLEUNIT["degree",0.0174532925199433]],
+        AXIS["longitude",east,
+            ORDER[2],
+            ANGLEUNIT["degree",0.0174532925199433]],
+    ID["EPSG",4326]]
+
+
+

This is pretty confusing looking. Without getting into the details, that long string says that this data has a geographic coordinate system (WGS84) with no projection. A convenient way to reference crs quickly is by using the EPSG code, a number that represents a standard projection and datum. You can check out a list of (lots!) of EPSG codes here.

+

We will use multiple EPSG codes in this lesson. Here they are, along with their more readable names:

+
    +
  • 3338: Alaska Albers (projected CRS)
  • +
  • 4326: WGS84 (World Geodetic System 1984), used in GPS (unprojected CRS)
  • +
  • 3857: Pseudo-Mercator, used in Google Maps, OpenStreetMap, Bing, ArcGIS, ESRI (projected CRS)
  • +
+

You will often need to transform your geospatial data from one coordinate system to another. The st_transform() function does this quickly for us. You may have noticed the maps above looked wonky because of the dateline. We might want to set a different projection for this data so it plots nicer. A good one for Alaska is called the Alaska Albers projection, with an EPSG code of 3338.

+
+
ak_regions_3338 <- ak_regions %>%
+    st_transform(crs = 3338)
+
+st_crs(ak_regions_3338)
+
+
Coordinate Reference System:
+  User input: EPSG:3338 
+  wkt:
+PROJCRS["NAD83 / Alaska Albers",
+    BASEGEOGCRS["NAD83",
+        DATUM["North American Datum 1983",
+            ELLIPSOID["GRS 1980",6378137,298.257222101,
+                LENGTHUNIT["metre",1]]],
+        PRIMEM["Greenwich",0,
+            ANGLEUNIT["degree",0.0174532925199433]],
+        ID["EPSG",4269]],
+    CONVERSION["Alaska Albers (meters)",
+        METHOD["Albers Equal Area",
+            ID["EPSG",9822]],
+        PARAMETER["Latitude of false origin",50,
+            ANGLEUNIT["degree",0.0174532925199433],
+            ID["EPSG",8821]],
+        PARAMETER["Longitude of false origin",-154,
+            ANGLEUNIT["degree",0.0174532925199433],
+            ID["EPSG",8822]],
+        PARAMETER["Latitude of 1st standard parallel",55,
+            ANGLEUNIT["degree",0.0174532925199433],
+            ID["EPSG",8823]],
+        PARAMETER["Latitude of 2nd standard parallel",65,
+            ANGLEUNIT["degree",0.0174532925199433],
+            ID["EPSG",8824]],
+        PARAMETER["Easting at false origin",0,
+            LENGTHUNIT["metre",1],
+            ID["EPSG",8826]],
+        PARAMETER["Northing at false origin",0,
+            LENGTHUNIT["metre",1],
+            ID["EPSG",8827]]],
+    CS[Cartesian,2],
+        AXIS["easting (X)",east,
+            ORDER[1],
+            LENGTHUNIT["metre",1]],
+        AXIS["northing (Y)",north,
+            ORDER[2],
+            LENGTHUNIT["metre",1]],
+    USAGE[
+        SCOPE["Topographic mapping (small scale)."],
+        AREA["United States (USA) - Alaska."],
+        BBOX[51.3,172.42,71.4,-129.99]],
+    ID["EPSG",3338]]
+
+
+
+
plot(ak_regions_3338)
+
+

+
+
+

Much better!

+
+
+
+

9.4 sf & the Tidyverse

+

sf objects can be used as a regular data.frame object in many operations. We already saw the results of plot() and head().

+

Since sf objects are data.frames, they play nicely with packages in the tidyverse. Here are a couple of simple examples:

+
+

9.4.1 select()

+
+
# returns the names of all the columns in dataset
+colnames(ak_regions_3338)
+
+
[1] "region_id" "region"    "mgmt_area" "geometry" 
+
+
+
+
ak_regions_3338 %>%
+    select(region)
+
+
Simple feature collection with 13 features and 1 field
+Geometry type: MULTIPOLYGON
+Dimension:     XY
+Bounding box:  xmin: -2175328 ymin: 405653 xmax: 1579226 ymax: 2383770
+Projected CRS: NAD83 / Alaska Albers
+# A tibble: 13 × 2
+   region                                                               geometry
+   <chr>                                                      <MULTIPOLYGON [m]>
+ 1 Aleutian Islands     (((-1156666 420855.1, -1159837 417990.3, -1161898 41694…
+ 2 Arctic               (((571289.9 2143072, 569941.5 2142691, 569158.2 2142146…
+ 3 Bristol Bay          (((-339688.6 973904.9, -339302 972297.3, -339229.2 9710…
+ 4 Chignik              (((-114381.9 649966.8, -112866.8 652065.8, -108836.8 65…
+ 5 Copper River         (((561012 1148301, 559393.7 1148169, 557797.7 1148492, …
+ 6 Kodiak               (((115112.5 983293, 113051.3 982825.9, 110801.3 983211.…
+ 7 Kotzebue             (((-678815.3 1819519, -677555.2 1820698, -675557.8 1821…
+ 8 Kuskokwim            (((-1030125 1281198, -1029858 1282333, -1028980 1284032…
+ 9 Cook Inlet           (((35214.98 1002457, 36660.3 1002038, 36953.11 1001186,…
+10 Norton Sound         (((-848357 1636692, -846510 1635203, -840513.7 1632225,…
+11 Prince William Sound (((426007.1 1087250, 426562.5 1088591, 427711.6 1089991…
+12 Southeast            (((1287777 744574.1, 1290183 745970.8, 1292940 746262.7…
+13 Yukon                (((-375318 1473998, -373723.9 1473487, -373064.8 147393…
+
+
+

Note the sticky geometry column! The geometry column will stay with your sf object even if it is not called explicitly.

+
+
+

9.4.2 filter()

+
+
unique(ak_regions_3338$region)
+
+
 [1] "Aleutian Islands"     "Arctic"               "Bristol Bay"         
+ [4] "Chignik"              "Copper River"         "Kodiak"              
+ [7] "Kotzebue"             "Kuskokwim"            "Cook Inlet"          
+[10] "Norton Sound"         "Prince William Sound" "Southeast"           
+[13] "Yukon"               
+
+
+
+
ak_regions_3338 %>%
+    filter(region == "Southeast")
+
+
Simple feature collection with 1 feature and 3 fields
+Geometry type: MULTIPOLYGON
+Dimension:     XY
+Bounding box:  xmin: 559475.7 ymin: 722450 xmax: 1579226 ymax: 1410576
+Projected CRS: NAD83 / Alaska Albers
+# A tibble: 1 × 4
+  region_id region    mgmt_area                                         geometry
+*     <int> <chr>         <dbl>                               <MULTIPOLYGON [m]>
+1        12 Southeast         1 (((1287777 744574.1, 1290183 745970.8, 1292940 …
+
+
+
+
+
+

9.5 Spatial Joins

+

You can also use the sf package to create spatial joins, useful for when you want to utilize two datasets together.

+
+
+
+ +
+
+Exercise: How many people live in each of these Alaska regions? +
+
+
+

We have some population data, but it gives the population by city, not by region. To determine the population per region we will need to:

+
    +
  1. Read in the population data from a csv and turn it into an sf object
  2. +
  3. Use a spatial join (st_join()) to assign each city to a region
  4. +
  5. Use group_by() and summarize() to calculate the total population by region
  6. +
  7. Save the spatial object you created using write_sf()
  8. +
+
+
+

1. Read in alaska_population.csv using read.csv()

+
+
# read in population data
+pop <- read_csv("data/alaska_population.csv")
+
+

Turn pop into a spatial object

+

The st_join() function is a spatial left join. The arguments for both the left and right tables are objects of class sf which means we will first need to turn our population data.frame with latitude and longitude coordinates into an sf object.

+

We can do this easily using the st_as_sf() function, which takes as arguments the coordinates and the crs. The remove = F specification here ensures that when we create our geometry column, we retain our original lat lng columns, which we will need later for plotting. Although it isn’t said anywhere explicitly in the file, let’s assume that the coordinate system used to reference the latitude longitude coordinates is WGS84, which has a crs number of 4326.

+
+
pop_4326 <- st_as_sf(pop,
+                     coords = c('lng', 'lat'),
+                     crs = 4326,
+                     remove = F)
+
+head(pop_4326)
+
+
Simple feature collection with 6 features and 5 fields
+Geometry type: POINT
+Dimension:     XY
+Bounding box:  xmin: -176.6581 ymin: 51.88 xmax: -154.1703 ymax: 62.68889
+Geodetic CRS:  WGS 84
+# A tibble: 6 × 6
+   year city       lat   lng population             geometry
+  <dbl> <chr>    <dbl> <dbl>      <dbl>          <POINT [°]>
+1  2015 Adak      51.9 -177.        122    (-176.6581 51.88)
+2  2015 Akhiok    56.9 -154.         84 (-154.1703 56.94556)
+3  2015 Akiachak  60.9 -161.        562 (-161.4314 60.90944)
+4  2015 Akiak     60.9 -161.        399 (-161.2139 60.91222)
+5  2015 Akutan    54.1 -166.        899 (-165.7731 54.13556)
+6  2015 Alakanuk  62.7 -165.        777 (-164.6153 62.68889)
+
+
+

2. Join population data with Alaska regions data using st_join()

+

Now we can do our spatial join! You can specify what geometry function the join uses (st_intersects, st_within, st_crosses, st_is_within_distance…) in the join argument. The geometry function you use will depend on what kind of operation you want to do, and the geometries of your shapefiles.

+

In this case, we want to find what region each city falls within, so we will use st_within.

+
+
pop_joined <- st_join(pop_4326, ak_regions_3338, join = st_within)
+
+

This gives an error!

+
Error: st_crs(x) == st_crs(y) is not TRUE
+

Turns out, this won’t work right now because our coordinate reference systems are not the same. Luckily, this is easily resolved using st_transform(), and projecting our population object into Alaska Albers.

+
+
pop_3338 <- st_transform(pop_4326, crs = 3338)
+
+
+
pop_joined <- st_join(pop_3338, ak_regions_3338, join = st_within)
+
+head(pop_joined)
+
+
Simple feature collection with 6 features and 8 fields
+Geometry type: POINT
+Dimension:     XY
+Bounding box:  xmin: -1537925 ymin: 472626.9 xmax: -10340.71 ymax: 1456223
+Projected CRS: NAD83 / Alaska Albers
+# A tibble: 6 × 9
+   year city     lat   lng population             geometry region_id region     
+  <dbl> <chr>  <dbl> <dbl>      <dbl>          <POINT [m]>     <int> <chr>      
+1  2015 Adak    51.9 -177.        122  (-1537925 472626.9)         1 Aleutian I…
+2  2015 Akhiok  56.9 -154.         84 (-10340.71 770998.4)         6 Kodiak     
+3  2015 Akiac…  60.9 -161.        562  (-400885.5 1236460)         8 Kuskokwim  
+4  2015 Akiak   60.9 -161.        399  (-389165.7 1235475)         8 Kuskokwim  
+5  2015 Akutan  54.1 -166.        899 (-766425.7 526057.8)         1 Aleutian I…
+6  2015 Alaka…  62.7 -165.        777  (-539724.9 1456223)        13 Yukon      
+# ℹ 1 more variable: mgmt_area <dbl>
+
+
+
+
+
+ +
+
+Exploring types of joins +
+
+
+

There are many different types of joins you can do with geospatial data. Examine the help page for these joins (?st_within() will get you there). What other joins types might be appropriate for examining the relationship between points and polygyons? What about two sets of polygons?

+
+
+

3. Calculate the total population by region using group_by() and summarize()

+

Next we compute the total population for each region. In this case, we want to do a group_by() and summarise() as this were a regular data.frame. Otherwise all of our point geometries would be included in the aggregation, which is not what we want. Our goal is just to get the total population by region. We remove the sticky geometry using as.data.frame(), on the advice of the sf::tidyverse help page.

+
+
pop_region <- pop_joined %>%
+    as.data.frame() %>%
+    group_by(region) %>%
+    summarise(total_pop = sum(population))
+
+head(pop_region)
+
+
# A tibble: 6 × 2
+  region           total_pop
+  <chr>                <dbl>
+1 Aleutian Islands      8840
+2 Arctic                8419
+3 Bristol Bay           6947
+4 Chignik                311
+5 Cook Inlet          408254
+6 Copper River          2294
+
+
+

And use a regular left_join() to get the information back to the Alaska region shapefile. Note that we need this step in order to regain our region geometries so that we can make some maps.

+
+
pop_region_3338 <- left_join(ak_regions_3338, pop_region, by = "region")
+
+# plot to check
+plot(pop_region_3338["total_pop"])
+
+

+
+
+

So far, we have learned how to use sf and dplyr to use a spatial join on two datasets and calculate a summary metric from the result of that join.

+
+
+
+ +
+
+sf and tidyverse best practices +
+
+
+

The group_by() and summarize() functions can also be used on sf objects to summarize within a dataset and combine geometries. Many of the tidyverse functions have methods specific for sf objects, some of which have additional arguments that wouldn’t be relevant to the data.frame methods. You can run ?sf::tidyverse to get documentation on the tidyverse sf methods.

+
+
+

Say we want to calculate the population by Alaska management area, as opposed to region.

+
+
pop_mgmt_338 <- pop_region_3338 %>%
+    group_by(mgmt_area) %>%
+    summarize(total_pop = sum(total_pop))
+
+plot(pop_mgmt_338["total_pop"])
+
+

+
+
+

Notice that the region geometries were combined into a single polygon for each management area.

+

If we don’t want to combine geometries, we can specify do_union = F as an argument.

+
+
pop_mgmt_3338 <- pop_region_3338 %>%
+    group_by(mgmt_area) %>%
+    summarize(total_pop = sum(total_pop), do_union = F)
+
+plot(pop_mgmt_3338["total_pop"])
+
+

+
+
+

4. Save the spatial object to a new file using write_sf()

+

Save the spatial object to disk using write_sf() and specifying the filename. Writing your file with the extension .shp will assume an ESRI driver driver, but there are many other format options available.

+
+
write_sf(pop_region_3338, "data/ak_regions_population.shp")
+
+
+

9.5.1 Visualize with ggplot

+

ggplot2 now has integrated functionality to plot sf objects using geom_sf().

+

We can plot sf objects just like regular data.frames using geom_sf.

+
+
ggplot(pop_region_3338) +
+    geom_sf(aes(fill = total_pop)) +
+    labs(fill = "Total Population") +
+    scale_fill_continuous(low = "khaki",
+                          high =  "firebrick",
+                          labels = comma) +
+    theme_bw()
+
+

+
+
+

We can also plot multiple shapefiles in the same plot. Say if we want to visualize rivers in Alaska, in addition to the location of communities, since many communities in Alaska are on rivers. We can read in a rivers shapefile, doublecheck the crs to make sure it is what we need, and then plot all three shapefiles - the regional population (polygons), the locations of cities (points), and the rivers (linestrings).

+
+
+
Coordinate Reference System:
+  User input: Albers 
+  wkt:
+PROJCRS["Albers",
+    BASEGEOGCRS["GCS_GRS 1980(IUGG, 1980)",
+        DATUM["D_unknown",
+            ELLIPSOID["GRS80",6378137,298.257222101,
+                LENGTHUNIT["metre",1,
+                    ID["EPSG",9001]]]],
+        PRIMEM["Greenwich",0,
+            ANGLEUNIT["Degree",0.0174532925199433]]],
+    CONVERSION["unnamed",
+        METHOD["Albers Equal Area",
+            ID["EPSG",9822]],
+        PARAMETER["Latitude of false origin",50,
+            ANGLEUNIT["Degree",0.0174532925199433],
+            ID["EPSG",8821]],
+        PARAMETER["Longitude of false origin",-154,
+            ANGLEUNIT["Degree",0.0174532925199433],
+            ID["EPSG",8822]],
+        PARAMETER["Latitude of 1st standard parallel",55,
+            ANGLEUNIT["Degree",0.0174532925199433],
+            ID["EPSG",8823]],
+        PARAMETER["Latitude of 2nd standard parallel",65,
+            ANGLEUNIT["Degree",0.0174532925199433],
+            ID["EPSG",8824]],
+        PARAMETER["Easting at false origin",0,
+            LENGTHUNIT["metre",1],
+            ID["EPSG",8826]],
+        PARAMETER["Northing at false origin",0,
+            LENGTHUNIT["metre",1],
+            ID["EPSG",8827]]],
+    CS[Cartesian,2],
+        AXIS["(E)",east,
+            ORDER[1],
+            LENGTHUNIT["metre",1,
+                ID["EPSG",9001]]],
+        AXIS["(N)",north,
+            ORDER[2],
+            LENGTHUNIT["metre",1,
+                ID["EPSG",9001]]]]
+
+
+
+
rivers_3338 <- read_sf("data/ak_rivers_simp.shp")
+st_crs(rivers_3338)
+
+

Note that although no EPSG code is set explicitly, with some sluething we can determine that this is EPSG:3338. This site is helpful for looking up EPSG codes.

+
+
ggplot() +
+    geom_sf(data = pop_region_3338, aes(fill = total_pop)) +
+    geom_sf(data = pop_3338, size = 0.5) +
+    geom_sf(data = rivers_3338,
+            aes(linewidth = StrOrder)) +
+    scale_linewidth(range = c(0.05, 0.5), guide = "none") +
+    labs(title = "Total Population by Alaska Region",
+         fill = "Total Population") +
+    scale_fill_continuous(low = "khaki",
+                          high =  "firebrick",
+                          labels = comma) +
+    theme_bw() 
+
+

+
+
+
+
+
+

9.6 Incorporate base maps into static maps using ggmap

+

The ggmap package has some functions that can render base maps (as raster objects) from open tile servers like Google Maps, Stamen, OpenStreetMap, and others.

+

We’ll need to transform our shapefile with population data by community to EPSG:3857 which is the crs used for rendering maps in Google Maps, Stamen, and OpenStreetMap, among others.

+
+
pop_3857 <- pop_3338 %>%
+    st_transform(crs = 3857)
+
+

Next, let’s grab a base map from the Stamen map tile server covering the region of interest. First we include a function that transforms the bounding box (which starts in EPSG:4326) to also be in the EPSG:3857 CRS, which is the projection that the map raster is returned in from Stamen. This is an issue with ggmap described in more detail here

+
+
# Define a function to fix the bbox to be in EPSG:3857
+# See https://github.com/dkahle/ggmap/issues/160#issuecomment-397055208
+ggmap_bbox_to_3857 <- function(map) {
+    if (!inherits(map, "ggmap"))
+        stop("map must be a ggmap object")
+    # Extract the bounding box (in lat/lon) from the ggmap to a numeric vector,
+    # and set the names to what sf::st_bbox expects:
+    map_bbox <- setNames(unlist(attr(map, "bb")),
+                         c("ymin", "xmin", "ymax", "xmax"))
+    
+    # Coonvert the bbox to an sf polygon, transform it to 3857,
+    # and convert back to a bbox (convoluted, but it works)
+    bbox_3857 <-
+        st_bbox(st_transform(st_as_sfc(st_bbox(map_bbox, crs = 4326)), 3857))
+    
+    # Overwrite the bbox of the ggmap object with the transformed coordinates
+    attr(map, "bb")$ll.lat <- bbox_3857["ymin"]
+    attr(map, "bb")$ll.lon <- bbox_3857["xmin"]
+    attr(map, "bb")$ur.lat <- bbox_3857["ymax"]
+    attr(map, "bb")$ur.lon <- bbox_3857["xmax"]
+    map
+}
+
+

Next, we define the bounding box of interest, and use get_stamenmap() to get the basemap. Then we run our function defined above on the result of the get_stamenmap() call.

+
+
bbox <- c(-170, 52,-130, 64) # this is roughly southern Alaska
+ak_map <- get_stamenmap(bbox, zoom = 4) # get base map
+ak_map_3857 <- ggmap_bbox_to_3857(ak_map) # fix the bbox to be in EPSG:3857
+
+

Finally, plot both the base raster map with the population data overlayed, which is easy now that everything is in the same projection (3857):

+
+
ggmap(ak_map_3857) +
+    geom_sf(data = pop_3857,
+            aes(color = population),
+            inherit.aes = F) +
+    scale_color_continuous(low = "khaki",
+                           high =  "firebrick",
+                           labels = comma)
+
+

+
+
+
+
+

9.7 Visualize sf objects with leaflet

+

We can also make an interactive map from our data above using leaflet.

+

leaflet (unlike ggplot) will project data for you. The catch is that you have to give it both a projection (like Alaska Albers), and that your shapefile must use a geographic coordinate system. This means that we need to use our shapefile with the 4326 EPSG code. Remember you can always check what crs you have set using st_crs.

+

Here we define a leaflet projection for Alaska Albers, and save it as a variable to use later.

+
+
epsg3338 <- leaflet::leafletCRS(
+    crsClass = "L.Proj.CRS",
+    code = "EPSG:3338",
+    proj4def =  "+proj=aea +lat_1=55 +lat_2=65 +lat_0=50 +lon_0=-154 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs",
+    resolutions = 2 ^ (16:7)
+)
+
+

You might notice that this looks familiar! The syntax is a bit different, but most of this information is also contained within the crs of our shapefile:

+
+
st_crs(pop_region_3338)
+
+
Coordinate Reference System:
+  User input: EPSG:3338 
+  wkt:
+PROJCRS["NAD83 / Alaska Albers",
+    BASEGEOGCRS["NAD83",
+        DATUM["North American Datum 1983",
+            ELLIPSOID["GRS 1980",6378137,298.257222101,
+                LENGTHUNIT["metre",1]]],
+        PRIMEM["Greenwich",0,
+            ANGLEUNIT["degree",0.0174532925199433]],
+        ID["EPSG",4269]],
+    CONVERSION["Alaska Albers (meters)",
+        METHOD["Albers Equal Area",
+            ID["EPSG",9822]],
+        PARAMETER["Latitude of false origin",50,
+            ANGLEUNIT["degree",0.0174532925199433],
+            ID["EPSG",8821]],
+        PARAMETER["Longitude of false origin",-154,
+            ANGLEUNIT["degree",0.0174532925199433],
+            ID["EPSG",8822]],
+        PARAMETER["Latitude of 1st standard parallel",55,
+            ANGLEUNIT["degree",0.0174532925199433],
+            ID["EPSG",8823]],
+        PARAMETER["Latitude of 2nd standard parallel",65,
+            ANGLEUNIT["degree",0.0174532925199433],
+            ID["EPSG",8824]],
+        PARAMETER["Easting at false origin",0,
+            LENGTHUNIT["metre",1],
+            ID["EPSG",8826]],
+        PARAMETER["Northing at false origin",0,
+            LENGTHUNIT["metre",1],
+            ID["EPSG",8827]]],
+    CS[Cartesian,2],
+        AXIS["easting (X)",east,
+            ORDER[1],
+            LENGTHUNIT["metre",1]],
+        AXIS["northing (Y)",north,
+            ORDER[2],
+            LENGTHUNIT["metre",1]],
+    USAGE[
+        SCOPE["Topographic mapping (small scale)."],
+        AREA["United States (USA) - Alaska."],
+        BBOX[51.3,172.42,71.4,-129.99]],
+    ID["EPSG",3338]]
+
+
+

Since leaflet requires that we use an unprojected coordinate system, let’s use st_transform() yet again to get back to WGS84.

+
+
pop_region_4326 <- pop_region_3338 %>% st_transform(crs = 4326)
+
+
+
m <- leaflet(options = leafletOptions(crs = epsg3338)) %>%
+    addPolygons(data = pop_region_4326,
+                fillColor = "gray",
+                weight = 1)
+
+m
+
+
+ +
+
+

We can add labels, legends, and a color scale.

+
+
pal <- colorNumeric(palette = "Reds", domain = pop_region_4326$total_pop)
+
+m <- leaflet(options = leafletOptions(crs = epsg3338)) %>%
+    addPolygons(
+        data = pop_region_4326,
+        fillColor = ~ pal(total_pop),
+        weight = 1,
+        color = "black",
+        fillOpacity = 1,
+        label = ~ region
+    ) %>%
+    addLegend(
+        position = "bottomleft",
+        pal = pal,
+        values = range(pop_region_4326$total_pop),
+        title = "Total Population"
+    )
+
+m
+
+
+ +
+
+

We can also add the individual communities, with popup labels showing their population, on top of that!

+
+
pal <- colorNumeric(palette = "Reds", domain = pop_region_4326$total_pop)
+
+m <- leaflet(options = leafletOptions(crs = epsg3338)) %>%
+    addPolygons(
+        data = pop_region_4326,
+        fillColor = ~ pal(total_pop),
+        weight = 1,
+        color = "black",
+        fillOpacity = 1
+    ) %>%
+    addCircleMarkers(
+        data = pop_4326,
+        lat = ~ lat,
+        lng = ~ lng,
+        radius = ~ log(population / 500),
+        # arbitrary scaling
+        fillColor = "gray",
+        fillOpacity = 1,
+        weight = 0.25,
+        color = "black",
+        label = ~ paste0(pop_4326$city, ", population ", comma(pop_4326$population))
+    ) %>%
+    addLegend(
+        position = "bottomleft",
+        pal = pal,
+        values = range(pop_region_4326$total_pop),
+        title = "Total Population"
+    )
+
+m
+
+
+ +
+
+
+
+

9.8 More Spatial Resources

+

There is a lot more functionality to sf including the ability to intersect polygons, calculate distance, create a buffer, and more. Here are some more great resources and tutorials for a deeper dive into this great package:

+ + + +
+ +
+ + +
+ + + + \ No newline at end of file diff --git a/public/session_09_files/figure-html/unnamed-chunk-18-1.png b/public/session_09_files/figure-html/unnamed-chunk-18-1.png new file mode 100644 index 00000000..3872dc37 Binary files /dev/null and b/public/session_09_files/figure-html/unnamed-chunk-18-1.png differ diff --git a/public/session_09_files/figure-html/unnamed-chunk-19-1.png b/public/session_09_files/figure-html/unnamed-chunk-19-1.png new file mode 100644 index 00000000..b499a675 Binary files /dev/null and b/public/session_09_files/figure-html/unnamed-chunk-19-1.png differ diff --git a/public/session_09_files/figure-html/unnamed-chunk-20-1.png b/public/session_09_files/figure-html/unnamed-chunk-20-1.png new file mode 100644 index 00000000..bcda06bb Binary files /dev/null and b/public/session_09_files/figure-html/unnamed-chunk-20-1.png differ diff --git a/public/session_09_files/figure-html/unnamed-chunk-21-1.png b/public/session_09_files/figure-html/unnamed-chunk-21-1.png new file mode 100644 index 00000000..4d0d3eae Binary files /dev/null and b/public/session_09_files/figure-html/unnamed-chunk-21-1.png differ diff --git a/public/session_09_files/figure-html/unnamed-chunk-24-1.png b/public/session_09_files/figure-html/unnamed-chunk-24-1.png new file mode 100644 index 00000000..0113aed3 Binary files /dev/null and b/public/session_09_files/figure-html/unnamed-chunk-24-1.png differ diff --git a/public/session_09_files/figure-html/unnamed-chunk-28-1.png b/public/session_09_files/figure-html/unnamed-chunk-28-1.png new file mode 100644 index 00000000..28a68d21 Binary files /dev/null and b/public/session_09_files/figure-html/unnamed-chunk-28-1.png differ diff --git a/public/session_09_files/figure-html/unnamed-chunk-3-1.png b/public/session_09_files/figure-html/unnamed-chunk-3-1.png new file mode 100644 index 00000000..02fff39a Binary files /dev/null and b/public/session_09_files/figure-html/unnamed-chunk-3-1.png differ diff --git a/public/session_09_files/figure-html/unnamed-chunk-8-1.png b/public/session_09_files/figure-html/unnamed-chunk-8-1.png new file mode 100644 index 00000000..bab99cbc Binary files /dev/null and b/public/session_09_files/figure-html/unnamed-chunk-8-1.png differ diff --git a/public/session_10.html b/public/session_10.html new file mode 100644 index 00000000..c9b41705 --- /dev/null +++ b/public/session_10.html @@ -0,0 +1,500 @@ + + + + + + + + + +NCEAS Open Science Synthesis for the Delta Science Program - 10  Introduction to Meta-Analysis + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

10  Introduction to Meta-Analysis

+
+
+ + +
+ + + + +
+ + +
+ + +
+ + + +
+ + + + +

ADD LINK TO MATERIALS

+ + + +
+ + +
+ + + + \ No newline at end of file diff --git a/public/session_11.html b/public/session_11.html new file mode 100644 index 00000000..9b520f3d --- /dev/null +++ b/public/session_11.html @@ -0,0 +1,952 @@ + + + + + + + + + +NCEAS Open Science Synthesis for the Delta Science Program - 11  Working with Text Data in R + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

11  Working with Text Data in R

+
+
+ + +
+ + + + +
+ + +
+ + +
+ + + +
+ + + + +
+

11.0.1 Learning Objectives

+
    +
  • What a token is and how they are used
  • +
  • How to use stop words
  • +
  • How to customize stop words
  • +
  • How to give structure to unstructured text
  • +
+
+
+

11.0.2 Introduction

+

Much of the information covered in this chapter is based on Text Mining with R: A Tidy Approach by Julia Silge and David Robinson. This is a great book if you want to go deeper into text analysis.

+

Text mining is the process by which unstructured text is transformed into a structured format to prepare it for analysis. This can range from the simple example we show in this lesson, to much more complicated processes such as using OCR (optical character recognition) to scan and extract text from pdfs, or web scraping.

+

Once text is in a structured format, analysis can be performed on it. The inherent benefit of quantitative text analysis is that it is highly scalable. With the right computational techniques, massive quantities of text can be mined and analyzed many, many orders of magnitude faster than it would take a human to do the same task. The downside, is that human language is inherently nuanced, and computers (as you may have noticed) think very differently than we do. In order for an analysis to capture this nuance, the tools and techniques for text analysis need to be set up with care, especially when the analysis becomes more complex.

+

There are a number of different types of text analysis. In this lesson we will show some simple examples of two: word frequency, and sentiment analysis.

+
+

Setup

+

First we’ll load the libraries we need for this lesson:

+
+
library(dplyr)
+library(tibble)
+library(readr)
+library(tidytext)
+library(wordcloud)
+library(reshape2)
+
+

Load the survey data back in using the code chunks below:

+
+
survey_raw <- read_csv("https://dev.nceas.ucsb.edu/knb/d1/mn/v2/object/urn%3Auuid%3A71cb8d0d-70d5-4752-abcd-e3bcf7f14783", show_col_types = FALSE)
+
+events <- read_csv("https://dev.nceas.ucsb.edu/knb/d1/mn/v2/object/urn%3Auuid%3A0a1dd2d8-e8db-4089-a176-1b557d6e2786", show_col_types = FALSE)
+
+
+
survey_clean <- survey_raw %>% 
+    select(-notes) %>% 
+    mutate(Q1 = if_else(Q1 == "1", "below expectations", Q1)) %>% 
+    mutate(Q2 = tolower(Q2))
+
+survey_joined <- left_join(survey_clean, events, by = "StartDate")
+
+
+
+

+

We are going to be working in the “tidy text format.” This format stipulates that the text column of our data frame contains rows with only one token per row. A token, in this case, is a meaningful unit of text. Depending on the analysis, that could be a word, two words, or phrase.

+

First, let’s create a data frame with responses to question 3, with the one token per row. We use the unnest_tokens function from tidytext, after selecting columns of interest.

+
+
q3 <- survey_joined %>% 
+    select(StartDate, location, Q3) %>% 
+    unnest_tokens(output = word, input = Q3)
+
+
+
+ +
+ +
+
+

You’ll see that we now have a very long data frame with only one word in each row of the text column. Some of the words aren’t so interesting though. The words that are likely not useful for analysis are called “stop words”. There is a list of stop words contained within the tidytext package and we can access it using the data function. We can then use the anti_join function to return only the words that are not in the stop word list.

+
+
data(stop_words)
+
+q3 <- anti_join(q3, stop_words)
+
+
Joining with `by = join_by(word)`
+
+
+
+
+ +
+ +
+
+

Now, we can do normal dplyr analysis to examine the most commonly used words in question 3. The count function is helpful here. We could also do a group_by and summarize and get the same result. We can also arrange the results, and get the top 10 using slice_head.

+
+
q3_top <- q3 %>% 
+    count(word) %>% 
+    arrange(-n) %>% 
+    slice_head(n = 10)
+
+
+
+ +
+ +
+
+
+
+

Term frequency

+

Right now, our counts of the most commonly used non-stop words are only moderately informative because they don’t take into context how many other words, responses, and courses there are. A widely used metric to analyze and draw conclusions from word frequency, including frequency within documents (or courses, in our case) is called tf-idf. This is the term frequency (number of appearances of a term divided by total number of terms), multiplied by the inverse document frequency (the natural log of the number of documents divided by the number of documents containing the term). The tidytext book has great examples on how to calculate this metric easily using some built in functions to the package.

+
+
+

+

Let’s do the same workflow for question 4:

+
+
q4 <- survey_joined %>% 
+    select(StartDate, location, Q4) %>% 
+    unnest_tokens(output = word, input = Q4) %>% 
+    anti_join(stop_words)
+
+
Joining with `by = join_by(word)`
+
+
q4_top <- q4 %>% 
+    count(word) %>% 
+    arrange(-n) %>% 
+    slice_head(n = 10)
+
+
+
+ +
+ +
+
+

Perhaps not surprisingly, the word data is mentioned a lot! In this case, it might be useful to add it to our stop words list. You can create a data.frame in place with your word, and an indication of the lexicon (in this case, your own, which we can call custom). Then we use rbind to bind that data frame with our previous stop words data frame.

+
+
custom_words <- data.frame(word = "data", lexicon = "custom")
+
+stop_words_full <- rbind(stop_words, custom_words)
+
+

Now we can run our question 4 analysis again, with the anti_join on our custom list.

+
+
q4 <- survey_joined %>% 
+    select(StartDate, location, Q4) %>% 
+    unnest_tokens(output = word, input = Q4) %>% 
+    anti_join(stop_words_full)
+
+
Joining with `by = join_by(word)`
+
+
q4_top <- q4 %>% 
+    count(word) %>% 
+    arrange(-n) %>% 
+    slice_head(n = 10)
+
+
+
+
+

11.1 Unstructured Text

+

The above example showed how to analyze text that was contained within a tabular format (a csv file). There are many other text formats that you might want to analyze, however. This might include pdf documents, websites, word documents, etc. Here, we’ll look at how to read in the text from a PDF document into an analysis pipeline like above.

+

Before we begin, it is important to understand that not all PDF documents can be processed this way. PDF files can store information in many ways, including both images and text. Some PDF documents, particularly older ones, or scanned documents, are images of text and the bytes making up the document do not contain a ‘readable’ version of the text in the image, it is an image not unlike one you would take with a camera. Other PDF documents will contain the text as character strings, along with the information on how to render it on the page (such as position and font). The analysis that follows will only work on PDF files that fit the second description of the format. If the PDF document you are trying to analyze is more like the first, you would need to first use a technique called Optical Character Recognition (OCR) to interpret the text in the image and store it in a parsable way. Since this document can be parsed, we’ll proceed without doing OCR.

+

First we’ll load another library, pdftools, which will read in our PDF, and the stringr library, which helps manipulate character strings.

+
+
library(pdftools)
+library(stringr)
+
+

Next, navigate to the dataset Elizabeth Rink and Gitte Adler Reimer. 2022. Population Dynamics in Greenland: A Multi-component Mixed-methods Study of Pregnancy Dynamics in Greenland (2014-2022). Arctic Data Center. doi:10.18739/A21Z41V1R.. Right click the download button next to the top PDF data file called ‘Translation_of_FG_8_Ilulissat_170410_0077.pdf’.

+

First we create a variable with a path to a location where we want to save the file.

+
+
path <- "data/Translation_of_FG_8_Ilulissat_170410_0077.pdf"
+
+

Then use download.file to download it and save it to that path.

+
+
download.file("https://arcticdata.io/metacat/d1/mn/v2/object/urn%3Auuid%3A34999083-2fa1-4222-ab27-53204327e8fc", path)
+
+

The pdf_text function extracts the text from the PDF file, returning a vector of character strings with a length equal to the number of pages in the file. So, our return value is loaded into R, but maybe not that useful yet because it is just a bunch of really long strings.

+
+
txt <- pdf_text(path)
+
+class(txt)
+
+
[1] "character"
+
+
+

Luckily, there is a function that will turn the pdf text data we just read in to a form that is compatible with the rest of the tidytext tools. The tibble::enframe function, converts the list into a data.frame. We then change one column name to describe what the column actually is (page number).

+
+
txt_clean <- txt %>%
+  enframe() %>% 
+  rename(page = name) 
+
+

We can do the same analysis as above, unnesting the tokens and removing stop words to get the most frequent words:

+
+
pdf_summary <- txt_clean %>%  
+  unnest_tokens(output = word, input = value) %>%
+  anti_join(stop_words) %>% 
+  count(word) %>% 
+  arrange(-n) %>% 
+  slice_head(n = 10)
+
+
Joining with `by = join_by(word)`
+
+
+
+
+ +
+ +
+
+

If we look at the result, and then back at the original document, it is clear that there is more work needed to get the data to an analyzable state. The header and footer of each page of the PDF were included in the text we analyzed, and since they are repeated every page (and aren’t really the subject of our inquiry anyway), should be removed from the text after we read it into R but before we try to calculate the most used words. It might also be beneficial to try and separate out the questions from responses, if we wanted to analyze just the responses or just the questions.

+

To help us clean things up, first let’s split our value column currently containing full pages of text by where there are double newlines (\n\n). You can see in the original PDF how this demarcates the responses, which contain single newlines within each paragraph, and two new lines (an empty line) between paragraphs. You can see an example of this within the text we have read in by examining just the first 500 characters of the first page of data.

+
+
substr(txt_clean$value[1], 1,500)
+
+
[1] "                             Population Dynamics in Greenland\n                                        Focus Group Meetings\n\nDate of the focus group meeting: Ilulissat April 10th, 2017\nName and title of the Researchers: Q3: Dr. Elizabeth Rink & Q1: Dr. Gitte Adler\nReimer\nName of the facilitator: Q2: Majbritt Didriksen Raal\nRecord No.: 170410_0077\n\nFG # 8\n\nQ2:     Ilulissat the April 10th, 2017, we are going to talk to the Professional Group.\n\nQ1:     Welcome, we are working on the final part of t"
+
+
+

To split our character vectors, we will use the str_split function. It splits a character vector according to a separator, and stores the values in a list. To show more clearly, let’s look at a dummy example. We can split a string of comma separated numbers into a list with each individual number.

+
+
x <- "1,2,3,4,5"
+str_split(x, ",")
+
+
[[1]]
+[1] "1" "2" "3" "4" "5"
+
+
+

In the real dataset, we’ll use str_split and mutate, which will create a list of values within each row of the value column. So each cell in the value column contains a list of values like the result of the example above. We can “flatten” this data so that each cell only has one value by using the unnest function, which takes as arguments the columns to flatten. Let’s take the example above, and make it a little more like our real data.

+

First turn the original dummy vector into a data frame, and do our split as before, this time using mutate.

+
+
x_df <- data.frame(x = x) %>% 
+  mutate(x = str_split(x, ","))
+x_df
+
+
              x
+1 1, 2, 3, 4, 5
+
+
+

Then you can run the unnest on the column of split values we just created.

+
+
x_df_flat <- x_df %>% 
+  tidyr::unnest(cols = x)
+
+x_df_flat
+
+
# A tibble: 5 × 1
+  x    
+  <chr>
+1 1    
+2 2    
+3 3    
+4 4    
+5 5    
+
+
+

Now that we know how this works, let’s do it on our dataset with the double newline character as the separator.

+
+
txt_clean <- txt_clean %>%
+  mutate(value = str_split(value, "\n\n")) %>% 
+  tidyr::unnest(cols = value)
+
+
+
DT::datatable(txt_clean, rownames = F)
+
+ +
+ +
+
+

You can see that our questions and answers are now easily visible because they all start with wither Q or A. The other lines are blank lines or header/footer lines from the document. So, let’s extract the first few characters of each line into a new column using substr, with the goal that we’ll run a filter for rows that start with Q or A, thus discarding all the other rows.

+

First, we extract the first 4 characters of each row and using mutate create a new column with those values called id.

+
+
txt_clean <- txt_clean %>% 
+  mutate(id = substr(value, 1, 4))
+
+

Let’s have a look at the unique values there:

+
+
unique(txt_clean$id)
+
+
 [1] "    "  "Date"  "FG #"  "Q2: "  "Q1: "  "A1: "  "PDG "  "A2: "  "\nQ2:"
+[10] "\nQ2." "\nPDG" ""      "A1  "  "Q3: " 
+
+
+

So unfortunately some of the text is a tiny bit garbled, there are newlines before at least some Q and A ids. We can use mutate again with str_replace to replace those \n with a blank value, which will remove them.

+
+
txt_clean <- txt_clean %>% 
+  mutate(id = substr(value, 1, 4)) %>% 
+  mutate(id = str_replace(id, "\n", ""))
+
+
+
unique(txt_clean$id)
+
+
 [1] "    " "Date" "FG #" "Q2: " "Q1: " "A1: " "PDG " "A2: " "Q2:"  "Q2." 
+[11] "PDG"  ""     "A1  " "Q3: "
+
+
+

Now we will use substr again to get the first two characters of each id.

+
+
txt_clean <- txt_clean %>% 
+  mutate(id = substr(value, 1, 4)) %>% 
+  mutate(id = str_replace(id, "\n", "")) %>% 
+  mutate(id = substr(id, 1, 2))
+
+
+
unique(txt_clean$id)
+
+
 [1] "  " "Da" "FG" "Q2" "Q1" "A1" "PD" "A2" ""   "Q3"
+
+
+

Finally, we can run the filter. Here, we filter for id values that start with either a Q or an A using the grepl function and a regular expression. We won’t go much into regular expression details, but there is a chapter in the appendix for more about how they work.

+

Here is an example of grepl in action. It returns a true or false for whether the value of x starts with (signified by ^) a Q or A (signified by QA in square brackets).

+
+
x <- c("Q3", "F1", "AAA", "FA")
+grepl("^[QA]", x)
+
+
[1]  TRUE FALSE  TRUE FALSE
+
+
+

So let’s run that within a filter which will return only rows where the grepl would return TRUE.

+
+
txt_clean <- txt_clean %>% 
+  mutate(id = substr(value, 1, 4)) %>% 
+  mutate(id = str_replace(id, "\n", "")) %>% 
+  mutate(id = substr(id, 1, 2)) %>% 
+  filter(grepl("^[QA]", id))
+
+
+
+ +
+ +
+
+

Finally, as our last cleaning step we replace all instances of the start of a string that contains a Q or A, followed by a digit and a colon, with an empty string (removing them from the beginning of the line.

+
+
txt_clean <- txt_clean %>% 
+  mutate(id = substr(value, 1, 4)) %>% 
+  mutate(id = str_replace(id, "\n", "")) %>% 
+  mutate(id = substr(id, 1, 2)) %>% 
+  filter(grepl("^[QA]", id)) %>% 
+  mutate(value = str_replace_all(value, "[QA][0-9]\\:", ""))
+
+
+
+ +
+ +
+
+

Finally, we can try the same analysis again as above to look for the most commonly used words.

+
+
pdf_summary <- txt_clean %>%  
+  unnest_tokens(output = word, input = value) %>%
+  anti_join(stop_words) %>% 
+  count(word) %>% 
+  arrange(-n) %>% 
+  slice_head(n = 10)
+
+
Joining with `by = join_by(word)`
+
+
+
+
+ +
+ +
+
+
+
+

11.2 Sentiment Analysis

+

In sentiment analysis, tokens (in this case our single words) are evaluated against a dictionary of words where a sentiment is assigned to the word. There are many different sentiment lexicons, some with single words, some with more than one word, and some that are aimed at particular disciplines. When embarking on a sentiment analysis project, choosing your lexicon is one that should be done with care. Sentiment analysis can also be done using machine learning algorithms.

+

With that in mind, we will next do a very simple sentiment analysis on our Q3 and Q4 answers using the bing lexicon from Bing Liu and collaborators, which ships with the tidytext package.

+

First we will use the get_sentiments function to load the lexicon.

+
+
bing <- get_sentiments("bing")
+
+

Next we do an inner join to return the words from question 3 that are contained within the lexicon.

+
+
q3_sent <- inner_join(q3, bing, by = "word")
+
+
+
+ +
+ +
+
+

There are a variety of directions you could go from here, analysis wise, such as calculating an overall sentiment index for that question, plotting sentiment against some other variable, or, making a fun word cloud like below! Here we bring in reshape2::acast to create a sentiment matrix for each word, and pass that into wordcloud::comparison.cloud to look at a wordcloud that indicates the frequency and sentiment of the words in our responses.

+
+
q3_sent %>% 
+  count(word, sentiment, sort = TRUE) %>%
+  acast(word ~ sentiment, value.var = "n", fill = 0) %>%
+  comparison.cloud(colors = c("gray20", "gray80"),
+                   max.words = 100, title.size = 2)
+
+

+
+
+

Let’s look at the question 4 word cloud:

+
+
q4 %>%
+  inner_join(bing, by = "word") %>% 
+  count(word, sentiment, sort = TRUE) %>%
+  acast(word ~ sentiment, value.var = "n", fill = 0) %>%
+  comparison.cloud(colors = c("gray20", "gray80"),
+                   max.words = 100, title.size = 2)
+
+

+
+
+
+
+

11.3 Summary

+

In this lesson, we learned:

+
    +
  • how to analyze structured text data from a survey using stop words and sentiment analysis
  • +
  • how to give structure to unstructured text data from a PDF to do some analysis using stop words and times words are used
  • +
+ + +
+ +
+ + +
+ + + + \ No newline at end of file diff --git a/public/session_11_files/figure-html/unnamed-chunk-45-1.png b/public/session_11_files/figure-html/unnamed-chunk-45-1.png new file mode 100644 index 00000000..74bdef9d Binary files /dev/null and b/public/session_11_files/figure-html/unnamed-chunk-45-1.png differ diff --git a/public/session_11_files/figure-html/unnamed-chunk-46-1.png b/public/session_11_files/figure-html/unnamed-chunk-46-1.png new file mode 100644 index 00000000..0cca7e20 Binary files /dev/null and b/public/session_11_files/figure-html/unnamed-chunk-46-1.png differ diff --git a/public/session_12.html b/public/session_12.html new file mode 100644 index 00000000..985cefa5 --- /dev/null +++ b/public/session_12.html @@ -0,0 +1,541 @@ + + + + + + + + + +NCEAS Open Science Synthesis for the Delta Science Program - 12  Working with US Census Data + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

12  Working with US Census Data

+
+
+ + +
+ + + + +
+ + +
+ + +
+ + + +
+ + + + +
+

Learning Objectives

+
+
+

12.1 Overview

+

(Chapter 1 - 5 min) - General view of US Census Data

+
+
+

12.2 Introduction to tidycensus

+

(Chapter 2 - 25-30 min)

+
    +
  • Basic data requests
  • +
  • Fundamentals of data package and the options it offers
  • +
+
+
+

12.3 Getting Census Data ready for analysis

+

(Chapter 3 - 20-25 min)

+
    +
  • Data wranglw again? Yes!
  • +
  • Handling errors in data
  • +
+
+
+

12.4 Visualizing Censis Data with ggplot2

+

(Chapter 4 - 20 min)

+
+
+

12.5 Maps and Census Data

+

( Chapter 5 and 6 - 10 min?)

+ + +
+ +
+ + +
+ + + + \ No newline at end of file diff --git a/public/session_13.html b/public/session_13.html new file mode 100644 index 00000000..1bd1a783 --- /dev/null +++ b/public/session_13.html @@ -0,0 +1,795 @@ + + + + + + + + + +NCEAS Open Science Synthesis for the Delta Science Program - 13  Reproducible Surveys + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

13  Reproducible Surveys

+
+
+ + +
+ + + + +
+ + +
+ + +
+ + + +
+ + + + +
+

13.0.1 Learning Objectives

+
    +
  • Overview of survey tools
  • +
  • Generating a reproducible survey report with Qualtrics
  • +
+
+
+

13.0.2 Introduction

+

Surveys and questionnaires are commonly used research methods within social science and other fields. For example, understanding regional and national population demographics, income, and education as part of the National Census activity, assessing audience perspectives on specific topics of research interest (e.g. the work by Tenopir and colleagues on Data Sharing by Scientists), evaluation of learning deliverables and outcomes, and consumer feedback on new and upcoming products. These are distinct from the use of the term survey within natural sciences, which might include geographical surveys (“the making of measurement in the field from which maps are drawn”), ecological surveys (“the process whereby a proposed development site is assess to establish any environmental impact the development may have”) or biodiversity surveys (“provide detailed information about biodiversity and community structure”) among others.

+

Although surveys can be conducted on paper or verbally, here we focus on surveys done via software tools. Needs will vary according to the nature of the research being undertaken. However, there is fundamental functionality that survey software should provide including:

+
    +
  1. The ability to create and customize questions
  2. +
  3. The ability to include different types of questions
  4. +
  5. The ability to distribute the survey and manage response collection
  6. +
  7. The ability to collect, summarize, and (securely) store response data
  8. +
+

More advanced features can include:

+
    +
  1. Visual design and templates - custom design might include institutional branding or aesthetic elements. Templates allow you to save these designs and apply to other surveys
  2. +
  3. Question piping - piping inserts answers from previous questions into upcoming questions and can personalize the survey experience for users
  4. +
  5. Survey logic - with question logic and skip logic you can control the inclusion / exclusion of questions based on previous responses
  6. +
  7. Randomization - the ability to randomize the presentation of questions within (blocks of) the survey
  8. +
  9. Branching - this allows for different users to take different paths through the survey. Similar to question logic but at a bigger scale
  10. +
  11. Language support - automated translation or multi-language presentation support
  12. +
  13. Shared administration - enables collaboration on the survey and response analysis
  14. +
  15. Survey export - ability to download (export) the survey instrument
  16. +
  17. Reports - survey response visualization and reporting tools
  18. +
  19. Institutional IRB approved - institutional IRB policy may require certain software be used for research purposes
  20. +
+

Commonly used survey software within academic (vs market) research include Qualtrics, Survey Monkey and Google Forms. Both qualtrics and survey monkey are licensed (with limited functionality available at no cost) and google forms is free.

+

+
+
+

13.0.3 Building workflows using Qualtrics

+

In this lesson we will use the qualtRics package to reproducible access some survey results set up for this course.

+
+

13.0.3.1 Survey Instrument

+

The survey is very short, only four questions. The first question is on it’s own page and is a consent question, after a couple of short paragraphs describing what the survey is, it’s purpose, how long it will take to complete, and who is conducting it. This type of information is required if the survey is governed by an IRB, and the content will depend on the type of research being conducted. In this case, this survey is not for research purposes, and thus is not governed by IRB, but we still include this information as it conforms to the Belmont Principles. The Belmont Principles identify the basic ethical principles that should underlie research involving human subjects.

+

+

The three main questions of the survey have three types of responses: a multiple choice answer, a multiple choice answer which also includes an “other” write in option, and a free text answer. We’ll use the results of this survey, which was sent out to NCEAS staff to fill out, to learn about how to create a reproducible survey report.

+

+

First, open a new RMarkdown document and add a chunk to load the libraries we’ll need for this lesson:

+
+
library(qualtRics)
+library(tidyr)
+library(knitr)
+library(ggplot2)
+library(kableExtra)
+library(dplyr)
+
+

Next, we need to set the API credentials. This function modifies the .Renviron file to set your API key and base URL so that you can access Qualtrics programmatically.

+

The API key is as good as a password, so care should be taken to not share it publicly. For example, you would never want to save it in a script. The function below is the rare exception of code that should be run in the console and not saved. It works in a way that you only need to run it once, unless you are working on a new computer or your credentials changed. Note that in this book, we have not shared the actual API key, for the reasons outlined above. You should have an e-mail with the API key in it. Copy and paste it as a string to the api_key argument in the function below:

+
+
qualtrics_api_credentials(api_key = "", base_url = "ucsb.co1.qualtrics.com", install = TRUE)
+
+
+
+

Aside

+

The .Renviron file is a special user controlled file that can create environment variables. Every time you open Rstudio, the variables in your environment file are loaded as…environment variables! Environment variables are named values that are accessible by your R process. They will not show up in your environment pane, but you can get a list of all of them using Sys.getenv(). Many are system defaults.

+
+
+

+

To view or edit your .Renviron file, you can use usethis::edit_r_environ().

+

To get a list of all the surveys in your Qualtrics instance, use the all_surveys function.

+
+
surveys <- all_surveys()
+kable(surveys) %>%
+    kable_styling()
+
+

This function returns a list of surveys, in this case only one, and information about each, including an identifier and it’s name. We’ll need that identifier later, so let’s go ahead and extract it using base R from the data frame.

+
+
i <- which(surveys$name == "Survey for Data Science Training")
+id <- surveys$id[i]
+
+

You can retrieve a list of the questions the survey asked using the survey_questions function and the survey id.

+
+
questions <- survey_questions(id)
+kable(questions) %>%
+    kable_styling()
+
+

This returns a data.frame with one row per question with columns for question id, question name, question text, and whether the question was required. This is helpful to have as a reference for when you are looking at the full survey results.

+

To get the full survey results, run fetch_survey with the survey id.

+
+
survey_results <- fetch_survey(id)
+
+

The survey results table has tons of information in it, not all of which will be relevant depending on your survey. The table has identifying information for the respondents (eg: ResponseID, IPaddress, RecipientEmail, RecipientFirstName, etc), much of which will be empty for this survey since it is anonymous. It also has information about the process of taking the survey, such as the StartDate, EndDate, Progress, and Duration. Finally, there are the answers to the questions asked, with columns labeled according to the qname column in the questions table (eg: Q1, Q2, Q3). Depending on the type of question, some questions might have multiple columns associated with them. We’ll have a look at this more closely in a later example.

+
+
+

Question 2

+

Let’s look at the responses to the second question in the survey, “How long have you been programming?” Remember, the first question was the consent question.

+

We’ll use the dplyr and tidyr tools we learned earlier to extract the information. Here are the steps:

+
    +
  • select the column we want (Q1)
  • +
  • group_by and summarize the values
  • +
+
+
q2 <- survey_results %>% 
+    select(Q2) %>% 
+    group_by(Q2) %>% 
+    summarise(n = n())
+
+

We can show these results in a table using the kable function from the knitr package:

+
+
kable(q2, col.names = c("How long have you been programming?",
+                        "Number of responses")) %>%
+    kable_styling()
+
+
+
+

13.0.3.2 Question 3

+

For question 3, we’ll use a similar workflow. For this question, however there are two columns containing survey answers. One contains the answers from the controlled vocabulary, the other contains any free text answers users entered.

+

To present this information, we’ll first show the results of the controlled answers as a plot. Below the plot, we’ll include a table showing all of the free text answers for the “other” option.

+
+
q3 <- survey_results %>% 
+    select(Q3) %>% 
+    group_by(Q3) %>% 
+    summarise(n = n())
+
+
+
ggplot(data = q3, mapping = aes(x = Q3, y = n)) +
+    geom_col() +
+    labs(x = "What language do you currently use most frequently?", y = "Number of reponses") +
+    theme_minimal()
+
+

Now we’ll extract the free text responses:

+
+
q3_text <- survey_results %>% 
+    select(Q3_7_TEXT) %>% 
+    drop_na()
+
+kable(q3_text, col.names = c("Other responses to 'What language do you currently use mose frequently?'")) %>% 
+    kable_styling()
+
+
+
+

13.0.3.3 Question 4

+

The last question is just a free text question, so we can just display the results as is.

+
+
q4 <- survey_results %>% 
+    select(Q4) %>% 
+    rename(`What data science tool or language are you most excited to learn next?` = Q4) %>% 
+    drop_na()
+
+kable(q4, col.names = "What data science tool or language are you most excited to learn next?") %>% 
+    kable_styling()
+
+
+
+
+

13.0.4 Other survey tools

+
+

Google forms

+

Google forms can be a great way to set up surveys, and it is very easy to interact with the results using R. The benefits of using google forms are a simple interface and easy sharing between collaborators, especially when writing the survey instrument.

+

The downside is that google forms has far fewer features than Qualtrics in terms of survey flow and appearance.

+

To show how we can link R into our survey workflows, I’ve set up a simple example survey here.

+

I’ve set up the results so that they are in a new spreadsheet here:. To access them, we will use the googlesheets4 package.

+

First, open up a new R script and load the googlesheets4 library:

+
+
library(googlesheets4)
+
+

Next, we can read the sheet in using the same URL that you would use to share the sheet with someone else. Right now, this sheet is public

+
+
responses <- read_sheet("https://docs.google.com/spreadsheets/d/1CSG__ejXQNZdwXc1QK8dKouxphP520bjUOnZ5SzOVP8/edit?usp=sharing")
+
+
✔ Reading from "Example Survey Form (Responses)".
+
+
+
✔ Range 'Form Responses 1'.
+
+
+

The first time you run this, you should get a popup window in your web browser asking you to confirm that you want to provide access to your google sheets via the tidyverse (googlesheets) package.

+

My dialog box looked like this:

+

+

Make sure you click the third check box enabling the Tidyverse API to see, edit, create, and delete your sheets. Note that you will have to tell it to do any of these actions via the R code you write.

+

When you come back to your R environment, you should have a data frame containing the data in your sheet! Let’s take a quick look at the structure of that sheet.

+
+
dplyr::glimpse(responses)
+
+
Rows: 10
+Columns: 5
+$ Timestamp                                              <dttm> 2022-04-15 13:…
+$ `To what degree did the event meet your expectations?` <chr> "Met expectatio…
+$ `To what degree did your knowledge improve?`           <chr> "Increase", "Si…
+$ `What did you like most about the event?`              <chr> "the cool instr…
+$ `What might you change about the event?`               <chr> "more snacks", …
+
+
+

So, now that we have the data in a standard R data.frame, we can easily summarize it and plot results. By default, the column names in the sheet are the long fully descriptive questions that were asked, which can be hard to type. We can save those questions into a vector for later reference, like when we want to use the question text for plot titles.

+
+
questions <- colnames(responses)[2:5]
+dplyr::glimpse(questions)
+
+
 chr [1:4] "To what degree did the event meet your expectations?" ...
+
+
+

We can make the responses data frame more compact by renaming the columns of the vector with short numbered names of the form Q1. Note that, by using a sequence, this should work for sheets from just a few columns to many hundreds of columns, and provides a consistent question naming convention.

+
+
names(questions) <- paste0("Q", seq(1:4))
+colnames(responses) <- c("Timestamp", names(questions))
+dplyr::glimpse(responses)
+
+
Rows: 10
+Columns: 5
+$ Timestamp <dttm> 2022-04-15 13:48:58, 2022-04-15 13:49:43, 2022-04-15 13:50:…
+$ Q1        <chr> "Met expectations", "Above expectations", "Above expectation…
+$ Q2        <chr> "Increase", "Significant increase", "Significant increase", …
+$ Q3        <chr> "the cool instructors", "R is rad!", "everything", "the pizz…
+$ Q4        <chr> "more snacks", "no pineapple pizza!", "nothing", "needs more…
+
+
+

Now that we’ve renamed our columns, let’s summarize the responses for the first question. We can use the same pattern that we usually do to split the data from Q1 into groups, then summarize it by counting the number of records in each group, and then merge the count of each group back together into a summarized data frame. We can then plot the Q1 results using ggplot:

+
+
q1 <- responses %>% 
+    dplyr::select(Q1) %>% 
+    dplyr::group_by(Q1) %>% 
+    dplyr::summarise(n = dplyr::n())
+
+ggplot2::ggplot(data = q1, mapping = aes(x = Q1, y = n)) +
+    geom_col() +
+    labs(x = questions[1], 
+         y = "Number of reponses",
+         title = "To what degree did the course meet expectations?") +
+    theme_minimal()
+
+
+
Bypassing authentication for public sheets
+

If you don’t want to go through a little interactive dialog every time you read in a sheet, and your sheet is public, you can run the function gs4_deauth() to access the sheet as a public user. This is helpful for cases when you want to run your code non-interactively. This is actually how I set it up for this book to build!

+
+
+
Challenge
+

Now that you have some background in accessing survey data from common tools, let’s do a quick exercise with Google Sheets. First, create a google sheet with the following columns that reflect a hypothetical survey result:

+
    +
  • Timestamp
  • +
  • Q1: How much did your proficiency with survey tools in R change? 1 = None, 2 = A little, 3 = A lot
  • +
  • Q2: How many years or partial years had you used R prior to this course?
  • +
  • Q3: How many years or partial years had you used statistics before this course?
  • +
+

Next populate the spreadhsheet with 5 to 10 rows of sample data that you make up. Now that you have the Google sheet in place, copy its URL and use it to do the following in R:

+
    +
  1. Load the google sheet into an R data.frame using the googlesheets package
  2. +
  3. Save the column headers as a vector of questions
  4. +
  5. Rename the question columns with short, consistent names
  6. +
  7. Summarize and plot the results for Q1 as a bar chart.
  8. +
+
+
+
+

Survey Monkey

+

Similar to Qualtrics and qualtRics, there is an open source R package for working with data in Survey Monkey: Rmonkey. However, the last updates were made 5 years ago, an eternity in the software world, so it may or may not still function as intended.

+

There are also commercial options available. For example, cdata have a driver and R package that enable access to an analysis of Survey Monkey data through R.

+ + +
+
+ +
+ + +
+ + + + \ No newline at end of file diff --git a/public/session_14.html b/public/session_14.html new file mode 100644 index 00000000..d9173a2d --- /dev/null +++ b/public/session_14.html @@ -0,0 +1,501 @@ + + + + + + + + + +NCEAS Open Science Synthesis for the Delta Science Program - 14  Guest Speaker + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

14  Guest Speaker

+
+
+ + +
+ + + + +
+ + +
+ + +
+ + + +
+ + + + + +

Add material

+ + + +
+ + +
+ + + + \ No newline at end of file diff --git a/public/session_15.html b/public/session_15.html new file mode 100644 index 00000000..c07b13ea --- /dev/null +++ b/public/session_15.html @@ -0,0 +1,500 @@ + + + + + + + + + +NCEAS Open Science Synthesis for the Delta Science Program - 15  Synthesis Time + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

15  Synthesis Time

+
+
+ + +
+ + + + +
+ + +
+ + +
+ + + +
+ + + + + + + + +
+ + +
+ + + + \ No newline at end of file diff --git a/public/session_16.html b/public/session_16.html new file mode 100644 index 00000000..69dd5ea7 --- /dev/null +++ b/public/session_16.html @@ -0,0 +1,1052 @@ + + + + + + + + + +NCEAS Open Science Synthesis for the Delta Science Program - 16  Shiny + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

16  Shiny

+
+
+ + +
+ + + + +
+ + +
+ + +
+ + + +
+ + + + +
+

16.0.1 Learning Objectives

+

In this lesson we will:

+
    +
  • review the capabilities in Shiny applications
  • +
  • learn about the basic layout for Shiny interfaces
  • +
  • learn about the server component for Shiny applications
  • +
  • build a simple shiny application for interactive plotting
  • +
+
+
+

16.0.2 Overview

+

Shiny is an R package for creating interactive data visualizations embedded in a web application that you and your colleagues can view with just a web browser. Shiny apps are relatively easy to construct, and provide interactive features for letting others share and explore data and analyses.

+

There are some really great examples of what Shiny can do on the RStudio webite like this one exploring movie metadata. A more scientific example is a tool from the SASAP project exploring proposal data from the Alaska Board of Fisheries. There is also an app for Delta monitoring efforts.

+

+

Most any kind of analysis and visualization that you can do in R can be turned into a useful interactive visualization for the web that lets people explore your data more intuitively But, a Shiny application is not the best way to preserve or archive your data. Instead, for preservation use a repository that is archival in its mission like the KNB Data Repository, Zenodo, or Dryad. This will assign a citable identifier to the specific version of your data, which you can then read in an interactive visualiztion with Shiny.

+

For example, the data for the Alaska Board of Fisheries application is published on the KNB and is citable as:

+

Meagan Krupa, Molly Cunfer, and Jeanette Clark. 2017. Alaska Board of Fisheries Proposals 1959-2016. Knowledge Network for Biocomplexity. doi:10.5063/F1QN652R.

+

While that is the best citation and archival location of the dataset, using Shiny, one can also provide an easy-to-use exploratory web application that you use to make your point that directly loads the data from the archival site. For example, the Board of Fisheries application above lets people who are not inherently familiar with the data to generate graphs showing the relationships between the variables in the dataset.

+

We’re going to create a simple shiny app with two sliders so we can interactively control inputs to an R function. These sliders will allow us to interactively control a plot.

+
+
+

16.0.3 Create a sample shiny application

+
    +
  • File > New > Shiny Web App…
  • +
  • Set some fields: creating a new Shiny app with RStudio +
      +
    • Name it “myapp” or something else
    • +
    • Select “Single File”
    • +
    • Choose to create it in a new folder called ‘shiny-demo’
    • +
    • Click Create
    • +
  • +
+

RStudio will create a new file called app.R that contains the Shiny application.
+Run it by choosing Run App from the RStudio editor header bar. This will bring up the default demo Shiny application, which plots a histogram and lets you control the number of bins in the plot.

+

+

Note that you can drag the slider to change the number of bins in the histogram.

+
+
+

16.0.4 Shiny architecture

+

A Shiny application consists of two functions, the ui and the server. The ui function is responsible for drawing the web page, while the server is responsible for any calculations and for creating any dynamic components to be rendered.

+

Each time that a user makes a change to one of the interactive widgets, the ui grabs the new value (say, the new slider min and max) and sends a request to the server to re-render the output, passing it the new input values that the user had set. These interactions can sometimes happen on one computer (e.g., if the application is running in your local RStudio instance). Other times, the ui runs on the web browser on one computer, while the server runs on a remote computer somewhere else on the Internet (e.g., if the application is deployed to a web server).

+

+
+
+

16.0.5 Interactive scatterplots

+

Let’s modify this application to plot Yolo bypass secchi disk data in a time-series, and allow aspects of the plot to be interactively changed.

+
+

16.0.5.1 Load data for the example

+

Use this code to load the data at the top of your app.R script. Note we are using contentId again, and we have filtered for some species of interest.

+
+
library(shiny)
+library(contentid)
+library(dplyr)
+library(ggplot2)
+library(lubridate)
+
+sha1 <- 'hash://sha1/317d7f840e598f5f3be732ab0e04f00a8051c6d0'
+delta.file <- contentid::resolve(sha1, registries=c("dataone"), store = TRUE)
+
+# fix the sample date format, and filter for species of interest
+delta_data <- read.csv(delta.file) %>% 
+    mutate(SampleDate = mdy(SampleDate))  %>% 
+    filter(grepl("Salmon|Striped Bass|Smelt|Sturgeon", CommonName))
+
+names(delta_data)
+
+
+
+

16.0.5.2 Add a simple timeseries using ggplot

+

We know there has been a lot of variation through time in the delta, so let’s plot a time-series of Secchi depth. We do so by switching out the histogram code for a simple ggplot, like so:

+
+
server <- function(input, output) {
+    
+    output$distPlot <- renderPlot({
+        
+        ggplot(delta_data, mapping = aes(SampleDate, Secchi)) +
+            geom_point(colour="red", size=4) +
+            theme_light()
+    })
+}
+
+

If you now reload the app, it will display the simple time-series instead of the histogram. At this point, we haven’t added any interactivity.

+

In a Shiny application, the server function provides the part of the application that creates our interactive components, and returns them to the user interface (ui) to be displayed on the page.

+
+
+

16.0.5.3 Add sliders to set the start and end date for the X axis

+

To make the plot interactive, first we need to modify our user interface to include widgits that we’ll use to control the plot. Specifically, we will add a new slider for setting the minDate parameter, and modify the existing slider to be used for the maxDate parameter. To do so, modify the sidebarPanel() call to include two sliderInput() function calls:

+
+
sidebarPanel(
+    sliderInput("minDate",
+                "Min Date:",
+                min = as.Date("1998-01-01"),
+                max = as.Date("2020-01-01"),
+                value = as.Date("1998-01-01")),
+    sliderInput("maxDate",
+                "Max Date:",
+                min = as.Date("1998-01-01"),
+                max = as.Date("2020-01-01"),
+                value = as.Date("2005-01-01"))
+)
+
+

If you reload the app, you’ll see two new sliders, but if you change them, they don’t make any changes to the plot. Let’s fix that.

+
+
+

16.0.5.4 Connect the slider values to the plot

+

Finally, to make the plot interactive, we can use the input and output variables that are passed into the server function to access the current values of the sliders. In Shiny, each UI component is given an input identifier when it is created, which is used as the name of the value in the input list. So, we can access the minimum depth as input$minDate and the max as input$maxDate. Let’s use these values now by adding limits to our X axis in the ggplot:

+
+
        ggplot(delta_data, mapping = aes(SampleDate, Secchi)) +
+            geom_point(colour="red", size=4) +
+            xlim(c(input$minDate,input$maxDate)) +
+            theme_light()
+
+

At this point, we have a fully interactive plot, and the sliders can be used to change the min and max of the Depth axis.

+

+

Looks so shiny!

+
+
+

16.0.5.5 Reversed Axes?

+

What happens if a clever user sets the minimum for the X axis at a greater value than the maximum? You’ll see that the direction of the X axis becomes reversed, and the plotted points display right to left. This is really an error condition. Rather than use two independent sliders, we can modify the first slider to output a range of values, which will prevent the min from being greater than the max. You do so by setting the value of the slider to a vector of length 2, representing the default min and max date for the slider, such as c(as.Date("1998-01-01"), as.Date("2020-01-01")). So, delete the second slider, rename the first, and provide a vector for the value, like this:

+
+
sliderInput("date",
+            "Date:",
+            min = as.Date("1998-01-01"),
+            max = as.Date("2020-01-01"),
+            value = c(as.Date("1998-01-01"), as.Date("2020-01-01")))
+)
+
+

Now, modify the ggplot to use this new date slider value, which now will be returned as a vector of length 2. The first element of the depth vector is the min, and the second is the max value on the slider.

+
+
        ggplot(delta_data, mapping = aes(SampleDate, Secchi)) +
+            geom_point(colour="red", size=4) +
+            xlim(c(input$date[1],input$date[2])) +
+            theme_light()
+
+

+
+
+
+

16.0.6 Extending the user interface with dynamic plots

+

If you want to display more than one plot in your application, and provide a different set of controls for each plot, the current layout would be too simple. Next we will extend the application to break the page up into vertical sections, and add a new plot in which the user can choose which variables are plotted. The current layout is set up such that the FluidPage contains the title element, and then a sidebarLayout, which is divided horizontally into a sidebarPanel and a mainPanel.

+

+
+

16.0.6.1 Vertical layout

+

To extend the layout, we will first nest the existing sidebarLayout in a new verticalLayout, which simply flows components down the page vertically. Then we will add a new sidebarLayout to contain the bottom controls and graph.

+

+

This mechanism of alternately nesting vertical and horizontal panels can be used to segment the screen into boxes with rules about how each of the panels is resized, and how the content flows when the browser window is resized. The sidebarLayout works to keep the sidebar about 1/3 of the box, and the main panel about 2/3, which is a good proportion for our controls and plots. Add the verticalLayout, and the second sidebarLayout for the second plot as follows:

+
+
    verticalLayout(
+        # Sidebar with a slider input for depth axis
+        sidebarLayout(
+            sidebarPanel(
+                sliderInput("date",
+                            "Date:",
+                            min = as.Date("1998-01-01"),
+                            max = as.Date("2020-01-01"),
+                            value = c(as.Date("1998-01-01"), as.Date("2020-01-01")))
+            ),
+            # Show a plot of the generated distribution
+            mainPanel(
+               plotOutput("distPlot")
+            )
+        ),
+
+        tags$hr(),
+
+        sidebarLayout(
+            sidebarPanel(
+                selectInput("x_variable", "X Variable", cols, selected = "SampleDate"),
+                selectInput("y_variable", "Y Variable", cols, selected = "Count"),
+                selectInput("color_variable", "Color", cols, selected = "CommonName")
+            ),
+
+            # Show a plot with configurable axes
+            mainPanel(
+                plotOutput("varPlot")
+            )
+        ),
+        tags$hr()
+
+

Note that the second sidebarPanel uses three selectInput elements to provide dropdown menus with the variable columns (cols) from our data frame. To manage that, we need to first set up the cols variable, which we do by saving the variables names from the delta_data data frame to a variable:

+
+
sha1 <- 'hash://sha1/317d7f840e598f5f3be732ab0e04f00a8051c6d0'
+delta.file <- contentid::resolve(sha1, registries=c("dataone"), store = TRUE)
+
+# fix the sample date format, and filter for species of interest
+delta_data <- read.csv(delta.file) %>% 
+    mutate(SampleDate = mdy(SampleDate))  %>% 
+    filter(grepl("Salmon|Striped Bass|Smelt|Sturgeon", CommonName))
+
+cols <- names(delta_data)
+
+
+
+

16.0.6.2 Add the dynamic plot

+

Because we named the second plot varPlot in our UI section, we now need to modify the server to produce this plot. Its very similar to the first plot, but this time we want to use the selected variables from the user controls to choose which variables are plotted. These variable names from the $input are character strings, and so would not be recognized as symbols in the aes mapping in ggplot. As recommended by the tidyverse authors, we use the non-standard evaluation syntax of .data[["colname"]] to access the variables.

+
+
    output$varPlot <- renderPlot({
+      ggplot(delta_data, aes(x = .data[[input$x_variable]],
+                             y = .data[[input$y_variable]],
+                             color = .data[[input$color_variable]])) +
+        geom_point(size = 4)+
+        theme_light()
+    })
+
+
+
+
+

16.0.7 Finishing touches: data citation

+

Citing the data that we used for this application is the right thing to do, and easy. You can add arbitrary HTML to the layout using utility functions in the tags list.

+
+
    # Application title
+    titlePanel("Yolo Bypass Fish and Water Quality Data"),
+    p("Data for this application are from: "),
+    tags$ul(
+        tags$li("Interagency Ecological Program: Fish catch and water quality data from the Sacramento River floodplain and tidal slough, collected by the Yolo Bypass Fish Monitoring Program, 1998-2018.",
+                tags$a("doi:10.6073/pasta/b0b15aef7f3b52d2c5adc10004c05a6f", href="http://doi.org/10.6073/pasta/b0b15aef7f3b52d2c5adc10004c05a6f")
+        )
+    ),
+    tags$br(),
+    tags$hr(),
+
+

The final application shows the data citation, the depth plot, and the configurable scatterplot in three distinct panels.

+

+
+
+

16.0.8 Publishing Shiny applications

+

Once you’ve finished your app, you’ll want to share it with others. To do so, you need to publish it to a server that is set up to handle Shiny apps.
+Your main choices are:

+
    +
  • shinyapps.io (Hosted by RStudio) +
      +
    • This is a service offered by RStudio, which is initially free for 5 or fewer apps and for limited run time, but has paid tiers to support more demanding apps. You can deploy your app using a single button push from within RStudio.
    • +
  • +
  • Shiny server (On premises) +
      +
    • This is an open source server which you can deploy for free on your own hardware. It requires more setup and configuration, but it can be used without a fee.
    • +
  • +
  • RStudio connect (On premises) +
      +
    • This is a paid product you install on your local hardware, and that contains the most advanced suite of services for hosting apps and RMarkdown reports. You can publish using a single button click from RStudio.
    • +
  • +
+

A comparison of publishing features is available from RStudio.

+
+

16.0.8.1 Publishing to shinyapps.io

+

The easiest path is to create an account on shinyapps.io, and then configure RStudio to use that account for publishing. Instructions for enabling your local RStudio to publish to your account are displayed when you first log into shinyapps.io:

+

+

Once your account is configured locally, you can simply use the Publish button from the application window in RStudio, and your app will be live before you know it!

+

+
+
+
+

16.0.9 Summary

+

Shiny is a fantastic way to quickly and efficiently provide data exploration for your data and code. We highly recommend it for its interactivity, but an archival-quality repository is the best long-term home for your data and products. In this example, we used data drawn directly from the EDI repository in our Shiny app, which offers both the preservation guarantees of an archive, plus the interactive data exploration from Shiny. You can utilize the full power of R and the tidyverse for writing your interactive applications.

+
+
+

16.0.10 Full source code for the final application

+
+
library(shiny)
+library(contentid)
+library(dplyr)
+library(ggplot2)
+library(lubridate)
+
+# read in the data from EDI
+sha1 <- 'hash://sha1/317d7f840e598f5f3be732ab0e04f00a8051c6d0'
+delta.file <- contentid::resolve(sha1, registries=c("dataone"), store = TRUE)
+
+# fix the sample date format, and filter for species of interest
+delta_data <- read.csv(delta.file) %>% 
+    mutate(SampleDate = mdy(SampleDate))  %>% 
+    filter(grepl("Salmon|Striped Bass|Smelt|Sturgeon", CommonName))
+
+cols <- names(delta_data)
+    
+
+
+# Define UI for application that draws a two plots
+ui <- fluidPage(
+    
+    # Application title and data  source
+    titlePanel("Sacramento River floodplain fish and water quality dataa"),
+    p("Data for this application are from: "),
+    tags$ul(
+        tags$li("Interagency Ecological Program: Fish catch and water quality data from the Sacramento River floodplain and tidal slough, collected by the Yolo Bypass Fish Monitoring Program, 1998-2018.",
+                tags$a("doi:10.6073/pasta/b0b15aef7f3b52d2c5adc10004c05a6f", href="http://doi.org/10.6073/pasta/b0b15aef7f3b52d2c5adc10004c05a6f")
+        )
+    ),
+    tags$br(),
+    tags$hr(),
+    
+    verticalLayout(
+        # Sidebar with a slider input for time axis
+        sidebarLayout(
+            sidebarPanel(
+                sliderInput("date",
+                            "Date:",
+                            min = as.Date("1998-01-01"),
+                            max = as.Date("2020-01-01"),
+                            value = c(as.Date("1998-01-01"), as.Date("2020-01-01")))
+            ),
+            # Show a plot of the generated timeseries
+            mainPanel(
+                plotOutput("distPlot")
+            )
+        ),
+        
+        tags$hr(),
+        
+        sidebarLayout(
+            sidebarPanel(
+                selectInput("x_variable", "X Variable", cols, selected = "SampleDate"),
+                selectInput("y_variable", "Y Variable", cols, selected = "Count"),
+                selectInput("color_variable", "Color", cols, selected = "CommonName")
+            ),
+            
+            # Show a plot with configurable axes
+            mainPanel(
+                plotOutput("varPlot")
+            )
+        ),
+        tags$hr()
+    )
+)
+
+# Define server logic required to draw the two plots
+server <- function(input, output) {
+    
+    #  turbidity plot
+    output$distPlot <- renderPlot({
+        
+        ggplot(delta_data, mapping = aes(SampleDate, Secchi)) +
+            geom_point(colour="red", size=4) +
+            xlim(c(input$date[1],input$date[2])) +
+            theme_light()
+    })
+    
+    # mix and  match plot
+    output$varPlot <- renderPlot({
+      ggplot(delta_data, aes(x = .data[[input$x_variable]],
+                             y = .data[[input$y_variable]],
+                             color = .data[[input$color_variable]])) +
+        geom_point(size = 4) +
+        theme_light()
+    })
+}
+
+
+# Run the application 
+shinyApp(ui = ui, server = server)
+
+
+
+

16.0.11 A shinier app with tabs and a map!

+
+
library(shiny)
+library(contentid)
+library(dplyr)
+library(tidyr)
+library(ggplot2)
+library(lubridate)
+library(shinythemes)
+library(sf)
+library(leaflet)
+library(snakecase)
+
+# read in the data from EDI
+sha1 <- 'hash://sha1/317d7f840e598f5f3be732ab0e04f00a8051c6d0'
+delta.file <- contentid::resolve(sha1, registries=c("dataone"), store = TRUE)
+
+# fix the sample date format, and filter for species of interest
+delta_data <- read.csv(delta.file) %>% 
+    mutate(SampleDate = mdy(SampleDate))  %>% 
+    filter(grepl("Salmon|Striped Bass|Smelt|Sturgeon", CommonName)) %>% 
+    rename(DissolvedOxygen = DO,
+           Ph = pH,
+           SpecificConductivity = SpCnd)
+
+cols <- names(delta_data)
+
+sites <- delta_data %>% 
+    distinct(StationCode, Latitude, Longitude) %>% 
+    drop_na() %>% 
+    st_as_sf(coords = c('Longitude','Latitude'), crs = 4269,  remove = FALSE)
+
+
+
+# Define UI for application
+ui <- fluidPage(
+    navbarPage(theme = shinytheme("flatly"), collapsible = TRUE,
+               HTML('<a style="text-decoration:none;cursor:default;color:#FFFFFF;" class="active" href="#">Sacramento River Floodplain Data</a>'), id="nav",
+               windowTitle = "Sacramento River floodplain fish and water quality data",
+               
+               tabPanel("Data Sources",
+                        verticalLayout(
+                            # Application title and data  source
+                            titlePanel("Sacramento River floodplain fish and water quality data"),
+                            p("Data for this application are from: "),
+                            tags$ul(
+                                tags$li("Interagency Ecological Program: Fish catch and water quality data from the Sacramento River floodplain and tidal slough, collected by the Yolo Bypass Fish Monitoring Program, 1998-2018.",
+                                        tags$a("doi:10.6073/pasta/b0b15aef7f3b52d2c5adc10004c05a6f", href="http://doi.org/10.6073/pasta/b0b15aef7f3b52d2c5adc10004c05a6f")
+                                )
+                            ),
+                            tags$br(),
+                            tags$hr(),
+                            p("Map of sampling locations"),
+                            mainPanel(leafletOutput("map"))
+                        )
+               ),
+               
+               tabPanel(
+                   "Explore",
+                   verticalLayout(
+                       mainPanel(
+                           plotOutput("distPlot"),
+                           width =  12,
+                           absolutePanel(id = "controls",
+                                         class = "panel panel-default",
+                                         top = 175, left = 75, width = 300, fixed=TRUE,
+                                         draggable = TRUE, height = "auto",
+                                         sliderInput("date",
+                                                     "Date:",
+                                                     min = as.Date("1998-01-01"),
+                                                     max = as.Date("2020-01-01"),
+                                                     value = c(as.Date("1998-01-01"), as.Date("2020-01-01")))
+                                         
+                           )
+                       ),
+                       
+                       tags$hr(),
+                       
+                       sidebarLayout(
+                           sidebarPanel(
+                               selectInput("x_variable", "X Variable", cols, selected = "SampleDate"),
+                               selectInput("y_variable", "Y Variable", cols, selected = "Count"),
+                               selectInput("color_variable", "Color", cols, selected = "CommonName")
+                           ),
+                           
+                           # Show a plot with configurable axes
+                           mainPanel(
+                               plotOutput("varPlot")
+                           )
+                       ),
+                       tags$hr()
+                   )
+               )
+    )
+)
+
+# Define server logic required to draw the two plots
+server <- function(input, output) {
+    
+    
+    output$map <- renderLeaflet({leaflet(sites) %>% 
+            addTiles() %>% 
+            addCircleMarkers(data = sites,
+                             lat = ~Latitude,
+                             lng = ~Longitude,
+                             radius = 10, # arbitrary scaling
+                             fillColor = "gray",
+                             fillOpacity = 1,
+                             weight = 0.25,
+                             color = "black",
+                             label = ~StationCode)
+    })
+    
+    #  turbidity plot
+    output$distPlot <- renderPlot({
+        
+        ggplot(delta_data, mapping = aes(SampleDate, Secchi)) +
+            geom_point(colour="red", size=4) +
+            xlim(c(input$date[1],input$date[2])) +
+            labs(x = "Sample Date", y = "Secchi Depth (m)") +
+            theme_light()
+    })
+    
+    # mix and  match plot
+    output$varPlot <- renderPlot({
+        ggplot(delta_data, mapping = aes(x = .data[[input$x_variable]],
+                                         y = .data[[input$y_variable]],
+                                         color = .data[[input$color_variable]])) +
+            labs(x = to_any_case(input$x_variable, case = "title"),
+                 y = to_any_case(input$y_variable, case = "title"),
+                 color = to_any_case(input$color_variable, case = "title")) +
+            geom_point(size=4) +
+            theme_light()
+    })
+}
+
+
+# Run the application 
+shinyApp(ui = ui, server = server)
+
+
+
+

16.0.12 Resources

+ + + +
+ +
+ + +
+ + + + \ No newline at end of file diff --git a/public/session_17.html b/public/session_17.html new file mode 100644 index 00000000..614054e9 --- /dev/null +++ b/public/session_17.html @@ -0,0 +1,622 @@ + + + + + + + + + +NCEAS Open Science Synthesis for the Delta Science Program - 17  Appendix + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+

17  Appendix

+
+
+ + +
+ + + + +
+ + +
+ + +
+ + + +
+ + + + +
+

Configuring Two-factor Authentication on GitHub

+
+

Learning Objectives

+
    +
  • Successfully setup two-factor authentication on GitHub
  • +
  • Recognize two-factor authentication jargon
  • +
+
+
+

17.1 Why Set up Two-factor Authentication (2FA)

+
    +
  1. Prevents unauthorized access
  2. +
  3. Strengthens your web security, especially if you have a compromised password
  4. +
  5. It is an increasing requirement for most websites and online applications or services
  6. +
+

In March 2023, GitHub announced that it will require 2FA for “all developers who contribute code on GitHub.com” (GitHub Blog). This rollout will be completed by the end of 2023.

+

All users have the flexibility to use their preferred 2FA method, including: TOTP, SMS, security keys, or GitHub Mobile app. GitHub strongly recommends using security keys and TOTPs. While SMS-based 2FA is available to use, it does not provide the same level of protection, and is no longer recommended under NIST (National Institute of Standards and Technology) 800-63B.

+
+

17.1.1 Additional information about 2FA on GitHub:

+ +
+
+
+ +
+
+For Your Reference +
+
+
+

Review the Glossary table to see a comprehensive list of two-factor authentication related terms and definitions

+
+
+
+
+
+

17.2 Steps for Configuring 2FA Using a TOTP App

+
+
+
+ +
+
+Additional Resource +
+
+
+

GitHub outlines these steps online in an article: Configuring two-factor authentication.

+
+
+
    +
  1. Download a TOTP app
  2. +
  3. Navigate to your account Settings (click your profile photo in the top right-hand corner)
  4. +
  5. In the “Access” section, click “Password and Authenticate”
  6. +
  7. In the “Two-factor authentication” section, click Enable two-factor authentication
  8. +
  9. Under “Setup authenticator app”, either: +
      +
    1. Scan the QR code with your TOTP app. After scanning, the app displays a six-digit code that you can enter on GitHub
    2. +
    3. If you can’t scan the QR code, click “enter this text code” to see a code that you can manually enter in your TOTP app instead
    4. +
  10. +
  11. On GitHub, type the code into the field under “Verify the code from the app”
  12. +
  13. Under “Save your recovery codes”, click “Download” to download your recovery codes. Save them to a secure location because your recovery codes can help you get back into your account if you lose access. +
      +
    1. After saving your two-factor recovery codes, click “I have saved my recovery codes” to enable two-factor authentication for your account
    2. +
  14. +
  15. Configure additional 2FA methods, if desired
  16. +
+
+
+

17.3 Glossary

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TermDefinition
Quick Response (QR) CodeA type of two-dimensional matrix barcode that contains specific information
Recovery CodeA unique code(s) used to reset passwords or regain access to accounts
Short Message Service (SMS)A text messaging service that allows mobile devices to exchange short text messages
Time-based one-time password (TOTP)A string of unique codes that changes based on time. Often, these appear as six-digit numbers that regenerate every 30 seconds
Two-factor Authentication (2FA)An identity and access management security method that requires two forms of identification to access accounts, resources, or data
+ + +
+
+ +
+ + +
+ + + + \ No newline at end of file diff --git a/public/site_libs/Proj4Leaflet-1.0.1/proj4leaflet.js b/public/site_libs/Proj4Leaflet-1.0.1/proj4leaflet.js new file mode 100644 index 00000000..eaa650c1 --- /dev/null +++ b/public/site_libs/Proj4Leaflet-1.0.1/proj4leaflet.js @@ -0,0 +1,272 @@ +(function (factory) { + var L, proj4; + if (typeof define === 'function' && define.amd) { + // AMD + define(['leaflet', 'proj4'], factory); + } else if (typeof module === 'object' && typeof module.exports === "object") { + // Node/CommonJS + L = require('leaflet'); + proj4 = require('proj4'); + module.exports = factory(L, proj4); + } else { + // Browser globals + if (typeof window.L === 'undefined' || typeof window.proj4 === 'undefined') + throw 'Leaflet and proj4 must be loaded first'; + factory(window.L, window.proj4); + } +}(function (L, proj4) { + if (proj4.__esModule && proj4.default) { + // If proj4 was bundled as an ES6 module, unwrap it to get + // to the actual main proj4 object. + // See discussion in https://github.com/kartena/Proj4Leaflet/pull/147 + proj4 = proj4.default; + } + + L.Proj = {}; + + L.Proj._isProj4Obj = function(a) { + return (typeof a.inverse !== 'undefined' && + typeof a.forward !== 'undefined'); + }; + + L.Proj.Projection = L.Class.extend({ + initialize: function(code, def, bounds) { + var isP4 = L.Proj._isProj4Obj(code); + this._proj = isP4 ? code : this._projFromCodeDef(code, def); + this.bounds = isP4 ? def : bounds; + }, + + project: function (latlng) { + var point = this._proj.forward([latlng.lng, latlng.lat]); + return new L.Point(point[0], point[1]); + }, + + unproject: function (point, unbounded) { + var point2 = this._proj.inverse([point.x, point.y]); + return new L.LatLng(point2[1], point2[0], unbounded); + }, + + _projFromCodeDef: function(code, def) { + if (def) { + proj4.defs(code, def); + } else if (proj4.defs[code] === undefined) { + var urn = code.split(':'); + if (urn.length > 3) { + code = urn[urn.length - 3] + ':' + urn[urn.length - 1]; + } + if (proj4.defs[code] === undefined) { + throw 'No projection definition for code ' + code; + } + } + + return proj4(code); + } + }); + + L.Proj.CRS = L.Class.extend({ + includes: L.CRS, + + options: { + transformation: new L.Transformation(1, 0, -1, 0) + }, + + initialize: function(a, b, c) { + var code, + proj, + def, + options; + + if (L.Proj._isProj4Obj(a)) { + proj = a; + code = proj.srsCode; + options = b || {}; + + this.projection = new L.Proj.Projection(proj, options.bounds); + } else { + code = a; + def = b; + options = c || {}; + this.projection = new L.Proj.Projection(code, def, options.bounds); + } + + L.Util.setOptions(this, options); + this.code = code; + this.transformation = this.options.transformation; + + if (this.options.origin) { + this.transformation = + new L.Transformation(1, -this.options.origin[0], + -1, this.options.origin[1]); + } + + if (this.options.scales) { + this._scales = this.options.scales; + } else if (this.options.resolutions) { + this._scales = []; + for (var i = this.options.resolutions.length - 1; i >= 0; i--) { + if (this.options.resolutions[i]) { + this._scales[i] = 1 / this.options.resolutions[i]; + } + } + } + + this.infinite = !this.options.bounds; + + }, + + scale: function(zoom) { + var iZoom = Math.floor(zoom), + baseScale, + nextScale, + scaleDiff, + zDiff; + if (zoom === iZoom) { + return this._scales[zoom]; + } else { + // Non-integer zoom, interpolate + baseScale = this._scales[iZoom]; + nextScale = this._scales[iZoom + 1]; + scaleDiff = nextScale - baseScale; + zDiff = (zoom - iZoom); + return baseScale + scaleDiff * zDiff; + } + }, + + zoom: function(scale) { + // Find closest number in this._scales, down + var downScale = this._closestElement(this._scales, scale), + downZoom = this._scales.indexOf(downScale), + nextScale, + nextZoom, + scaleDiff; + // Check if scale is downScale => return array index + if (scale === downScale) { + return downZoom; + } + if (downScale === undefined) { + return -Infinity; + } + // Interpolate + nextZoom = downZoom + 1; + nextScale = this._scales[nextZoom]; + if (nextScale === undefined) { + return Infinity; + } + scaleDiff = nextScale - downScale; + return (scale - downScale) / scaleDiff + downZoom; + }, + + distance: L.CRS.Earth.distance, + + R: L.CRS.Earth.R, + + /* Get the closest lowest element in an array */ + _closestElement: function(array, element) { + var low; + for (var i = array.length; i--;) { + if (array[i] <= element && (low === undefined || low < array[i])) { + low = array[i]; + } + } + return low; + } + }); + + L.Proj.GeoJSON = L.GeoJSON.extend({ + initialize: function(geojson, options) { + this._callLevel = 0; + L.GeoJSON.prototype.initialize.call(this, geojson, options); + }, + + addData: function(geojson) { + var crs; + + if (geojson) { + if (geojson.crs && geojson.crs.type === 'name') { + crs = new L.Proj.CRS(geojson.crs.properties.name); + } else if (geojson.crs && geojson.crs.type) { + crs = new L.Proj.CRS(geojson.crs.type + ':' + geojson.crs.properties.code); + } + + if (crs !== undefined) { + this.options.coordsToLatLng = function(coords) { + var point = L.point(coords[0], coords[1]); + return crs.projection.unproject(point); + }; + } + } + + // Base class' addData might call us recursively, but + // CRS shouldn't be cleared in that case, since CRS applies + // to the whole GeoJSON, inluding sub-features. + this._callLevel++; + try { + L.GeoJSON.prototype.addData.call(this, geojson); + } finally { + this._callLevel--; + if (this._callLevel === 0) { + delete this.options.coordsToLatLng; + } + } + } + }); + + L.Proj.geoJson = function(geojson, options) { + return new L.Proj.GeoJSON(geojson, options); + }; + + L.Proj.ImageOverlay = L.ImageOverlay.extend({ + initialize: function (url, bounds, options) { + L.ImageOverlay.prototype.initialize.call(this, url, null, options); + this._projectedBounds = bounds; + }, + + // Danger ahead: Overriding internal methods in Leaflet. + // Decided to do this rather than making a copy of L.ImageOverlay + // and doing very tiny modifications to it. + // Future will tell if this was wise or not. + _animateZoom: function (event) { + var scale = this._map.getZoomScale(event.zoom); + var northWest = L.point(this._projectedBounds.min.x, this._projectedBounds.max.y); + var offset = this._projectedToNewLayerPoint(northWest, event.zoom, event.center); + + L.DomUtil.setTransform(this._image, offset, scale); + }, + + _reset: function () { + var zoom = this._map.getZoom(); + var pixelOrigin = this._map.getPixelOrigin(); + var bounds = L.bounds( + this._transform(this._projectedBounds.min, zoom)._subtract(pixelOrigin), + this._transform(this._projectedBounds.max, zoom)._subtract(pixelOrigin) + ); + var size = bounds.getSize(); + + L.DomUtil.setPosition(this._image, bounds.min); + this._image.style.width = size.x + 'px'; + this._image.style.height = size.y + 'px'; + }, + + _projectedToNewLayerPoint: function (point, zoom, center) { + var viewHalf = this._map.getSize()._divideBy(2); + var newTopLeft = this._map.project(center, zoom)._subtract(viewHalf)._round(); + var topLeft = newTopLeft.add(this._map._getMapPanePos()); + + return this._transform(point, zoom)._subtract(topLeft); + }, + + _transform: function (point, zoom) { + var crs = this._map.options.crs; + var transformation = crs.transformation; + var scale = crs.scale(zoom); + + return transformation.transform(point, scale); + } + }); + + L.Proj.imageOverlay = function (url, bounds, options) { + return new L.Proj.ImageOverlay(url, bounds, options); + }; + + return L.Proj; +})); diff --git a/public/site_libs/bootstrap/bootstrap-icons.css b/public/site_libs/bootstrap/bootstrap-icons.css new file mode 100644 index 00000000..94f19404 --- /dev/null +++ b/public/site_libs/bootstrap/bootstrap-icons.css @@ -0,0 +1,2018 @@ +@font-face { + font-display: block; + font-family: "bootstrap-icons"; + src: +url("./bootstrap-icons.woff?2ab2cbbe07fcebb53bdaa7313bb290f2") format("woff"); +} + +.bi::before, +[class^="bi-"]::before, +[class*=" bi-"]::before { + display: inline-block; + font-family: bootstrap-icons !important; + font-style: normal; + font-weight: normal !important; + font-variant: normal; + text-transform: none; + line-height: 1; + vertical-align: -.125em; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.bi-123::before { content: "\f67f"; } +.bi-alarm-fill::before { content: "\f101"; } +.bi-alarm::before { content: "\f102"; } +.bi-align-bottom::before { content: "\f103"; } +.bi-align-center::before { content: "\f104"; } +.bi-align-end::before { content: "\f105"; } +.bi-align-middle::before { content: "\f106"; } +.bi-align-start::before { content: "\f107"; } +.bi-align-top::before { content: "\f108"; } +.bi-alt::before { content: "\f109"; } +.bi-app-indicator::before { content: "\f10a"; } +.bi-app::before { content: "\f10b"; } +.bi-archive-fill::before { content: "\f10c"; } +.bi-archive::before { content: "\f10d"; } +.bi-arrow-90deg-down::before { content: "\f10e"; } +.bi-arrow-90deg-left::before { content: "\f10f"; } +.bi-arrow-90deg-right::before { content: "\f110"; } +.bi-arrow-90deg-up::before { content: "\f111"; } +.bi-arrow-bar-down::before { content: "\f112"; } +.bi-arrow-bar-left::before { content: "\f113"; } +.bi-arrow-bar-right::before { content: "\f114"; } +.bi-arrow-bar-up::before { content: "\f115"; } +.bi-arrow-clockwise::before { content: "\f116"; } +.bi-arrow-counterclockwise::before { content: "\f117"; } +.bi-arrow-down-circle-fill::before { content: "\f118"; } +.bi-arrow-down-circle::before { content: "\f119"; } +.bi-arrow-down-left-circle-fill::before { content: "\f11a"; } +.bi-arrow-down-left-circle::before { content: "\f11b"; } +.bi-arrow-down-left-square-fill::before { content: "\f11c"; } +.bi-arrow-down-left-square::before { content: "\f11d"; } +.bi-arrow-down-left::before { content: "\f11e"; } +.bi-arrow-down-right-circle-fill::before { content: "\f11f"; } +.bi-arrow-down-right-circle::before { content: "\f120"; } +.bi-arrow-down-right-square-fill::before { content: "\f121"; } +.bi-arrow-down-right-square::before { content: "\f122"; } +.bi-arrow-down-right::before { content: "\f123"; } +.bi-arrow-down-short::before { content: "\f124"; } +.bi-arrow-down-square-fill::before { content: "\f125"; } +.bi-arrow-down-square::before { content: "\f126"; } +.bi-arrow-down-up::before { content: "\f127"; } +.bi-arrow-down::before { content: "\f128"; } +.bi-arrow-left-circle-fill::before { content: "\f129"; } +.bi-arrow-left-circle::before { content: "\f12a"; } +.bi-arrow-left-right::before { content: "\f12b"; } +.bi-arrow-left-short::before { content: "\f12c"; } +.bi-arrow-left-square-fill::before { content: "\f12d"; } +.bi-arrow-left-square::before { content: "\f12e"; } +.bi-arrow-left::before { content: "\f12f"; } +.bi-arrow-repeat::before { content: "\f130"; } +.bi-arrow-return-left::before { content: "\f131"; } +.bi-arrow-return-right::before { content: "\f132"; } +.bi-arrow-right-circle-fill::before { content: "\f133"; } +.bi-arrow-right-circle::before { content: "\f134"; } +.bi-arrow-right-short::before { content: "\f135"; } +.bi-arrow-right-square-fill::before { content: "\f136"; } +.bi-arrow-right-square::before { content: "\f137"; } +.bi-arrow-right::before { content: "\f138"; } +.bi-arrow-up-circle-fill::before { content: "\f139"; } +.bi-arrow-up-circle::before { content: "\f13a"; } +.bi-arrow-up-left-circle-fill::before { content: "\f13b"; } +.bi-arrow-up-left-circle::before { content: "\f13c"; } +.bi-arrow-up-left-square-fill::before { content: "\f13d"; } +.bi-arrow-up-left-square::before { content: "\f13e"; } +.bi-arrow-up-left::before { content: "\f13f"; } +.bi-arrow-up-right-circle-fill::before { content: "\f140"; } +.bi-arrow-up-right-circle::before { content: "\f141"; } +.bi-arrow-up-right-square-fill::before { content: "\f142"; } +.bi-arrow-up-right-square::before { content: "\f143"; } +.bi-arrow-up-right::before { content: "\f144"; } +.bi-arrow-up-short::before { content: "\f145"; } +.bi-arrow-up-square-fill::before { content: "\f146"; } +.bi-arrow-up-square::before { content: "\f147"; } +.bi-arrow-up::before { content: "\f148"; } +.bi-arrows-angle-contract::before { content: "\f149"; } +.bi-arrows-angle-expand::before { content: "\f14a"; } +.bi-arrows-collapse::before { content: "\f14b"; } +.bi-arrows-expand::before { content: "\f14c"; } +.bi-arrows-fullscreen::before { content: "\f14d"; } +.bi-arrows-move::before { content: "\f14e"; } +.bi-aspect-ratio-fill::before { content: "\f14f"; } +.bi-aspect-ratio::before { content: "\f150"; } +.bi-asterisk::before { content: "\f151"; } +.bi-at::before { content: "\f152"; } +.bi-award-fill::before { content: "\f153"; } +.bi-award::before { content: "\f154"; } +.bi-back::before { content: "\f155"; } +.bi-backspace-fill::before { content: "\f156"; } +.bi-backspace-reverse-fill::before { content: "\f157"; } +.bi-backspace-reverse::before { content: "\f158"; } +.bi-backspace::before { content: "\f159"; } +.bi-badge-3d-fill::before { content: "\f15a"; } +.bi-badge-3d::before { content: "\f15b"; } +.bi-badge-4k-fill::before { content: "\f15c"; } +.bi-badge-4k::before { content: "\f15d"; } +.bi-badge-8k-fill::before { content: "\f15e"; } +.bi-badge-8k::before { content: "\f15f"; } +.bi-badge-ad-fill::before { content: "\f160"; } +.bi-badge-ad::before { content: "\f161"; } +.bi-badge-ar-fill::before { content: "\f162"; } +.bi-badge-ar::before { content: "\f163"; } +.bi-badge-cc-fill::before { content: "\f164"; } +.bi-badge-cc::before { content: "\f165"; } +.bi-badge-hd-fill::before { content: "\f166"; } +.bi-badge-hd::before { content: "\f167"; } +.bi-badge-tm-fill::before { content: "\f168"; } +.bi-badge-tm::before { content: "\f169"; } +.bi-badge-vo-fill::before { content: "\f16a"; } +.bi-badge-vo::before { content: "\f16b"; } +.bi-badge-vr-fill::before { content: "\f16c"; } +.bi-badge-vr::before { content: "\f16d"; } +.bi-badge-wc-fill::before { content: "\f16e"; } +.bi-badge-wc::before { content: "\f16f"; } +.bi-bag-check-fill::before { content: "\f170"; } +.bi-bag-check::before { content: "\f171"; } +.bi-bag-dash-fill::before { content: "\f172"; } +.bi-bag-dash::before { content: "\f173"; } +.bi-bag-fill::before { content: "\f174"; } +.bi-bag-plus-fill::before { content: "\f175"; } +.bi-bag-plus::before { content: "\f176"; } +.bi-bag-x-fill::before { content: "\f177"; } +.bi-bag-x::before { content: "\f178"; } +.bi-bag::before { content: "\f179"; } +.bi-bar-chart-fill::before { content: "\f17a"; } +.bi-bar-chart-line-fill::before { content: "\f17b"; } +.bi-bar-chart-line::before { content: "\f17c"; } +.bi-bar-chart-steps::before { content: "\f17d"; } +.bi-bar-chart::before { content: "\f17e"; } +.bi-basket-fill::before { content: "\f17f"; } +.bi-basket::before { content: "\f180"; } +.bi-basket2-fill::before { content: "\f181"; } +.bi-basket2::before { content: "\f182"; } +.bi-basket3-fill::before { content: "\f183"; } +.bi-basket3::before { content: "\f184"; } +.bi-battery-charging::before { content: "\f185"; } +.bi-battery-full::before { content: "\f186"; } +.bi-battery-half::before { content: "\f187"; } +.bi-battery::before { content: "\f188"; } +.bi-bell-fill::before { content: "\f189"; } +.bi-bell::before { content: "\f18a"; } +.bi-bezier::before { content: "\f18b"; } +.bi-bezier2::before { content: "\f18c"; } +.bi-bicycle::before { content: "\f18d"; } +.bi-binoculars-fill::before { content: "\f18e"; } +.bi-binoculars::before { content: "\f18f"; } +.bi-blockquote-left::before { content: "\f190"; } +.bi-blockquote-right::before { content: "\f191"; } +.bi-book-fill::before { content: "\f192"; } +.bi-book-half::before { content: "\f193"; } +.bi-book::before { content: "\f194"; } +.bi-bookmark-check-fill::before { content: "\f195"; } +.bi-bookmark-check::before { content: "\f196"; } +.bi-bookmark-dash-fill::before { content: "\f197"; } +.bi-bookmark-dash::before { content: "\f198"; } +.bi-bookmark-fill::before { content: "\f199"; } +.bi-bookmark-heart-fill::before { content: "\f19a"; } +.bi-bookmark-heart::before { content: "\f19b"; } +.bi-bookmark-plus-fill::before { content: "\f19c"; } +.bi-bookmark-plus::before { content: "\f19d"; } +.bi-bookmark-star-fill::before { content: "\f19e"; } +.bi-bookmark-star::before { content: "\f19f"; } +.bi-bookmark-x-fill::before { content: "\f1a0"; } +.bi-bookmark-x::before { content: "\f1a1"; } +.bi-bookmark::before { content: "\f1a2"; } +.bi-bookmarks-fill::before { content: "\f1a3"; } +.bi-bookmarks::before { content: "\f1a4"; } +.bi-bookshelf::before { content: "\f1a5"; } +.bi-bootstrap-fill::before { content: "\f1a6"; } +.bi-bootstrap-reboot::before { content: "\f1a7"; } +.bi-bootstrap::before { content: "\f1a8"; } +.bi-border-all::before { content: "\f1a9"; } +.bi-border-bottom::before { content: "\f1aa"; } +.bi-border-center::before { content: "\f1ab"; } +.bi-border-inner::before { content: "\f1ac"; } +.bi-border-left::before { content: "\f1ad"; } +.bi-border-middle::before { content: "\f1ae"; } +.bi-border-outer::before { content: "\f1af"; } +.bi-border-right::before { content: "\f1b0"; } +.bi-border-style::before { content: "\f1b1"; } +.bi-border-top::before { content: "\f1b2"; } +.bi-border-width::before { content: "\f1b3"; } +.bi-border::before { content: "\f1b4"; } +.bi-bounding-box-circles::before { content: "\f1b5"; } +.bi-bounding-box::before { content: "\f1b6"; } +.bi-box-arrow-down-left::before { content: "\f1b7"; } +.bi-box-arrow-down-right::before { content: "\f1b8"; } +.bi-box-arrow-down::before { content: "\f1b9"; } +.bi-box-arrow-in-down-left::before { content: "\f1ba"; } +.bi-box-arrow-in-down-right::before { content: "\f1bb"; } +.bi-box-arrow-in-down::before { content: "\f1bc"; } +.bi-box-arrow-in-left::before { content: "\f1bd"; } +.bi-box-arrow-in-right::before { content: "\f1be"; } +.bi-box-arrow-in-up-left::before { content: "\f1bf"; } +.bi-box-arrow-in-up-right::before { content: "\f1c0"; } +.bi-box-arrow-in-up::before { content: "\f1c1"; } +.bi-box-arrow-left::before { content: "\f1c2"; } +.bi-box-arrow-right::before { content: "\f1c3"; } +.bi-box-arrow-up-left::before { content: "\f1c4"; } +.bi-box-arrow-up-right::before { content: "\f1c5"; } +.bi-box-arrow-up::before { content: "\f1c6"; } +.bi-box-seam::before { content: "\f1c7"; } +.bi-box::before { content: "\f1c8"; } +.bi-braces::before { content: "\f1c9"; } +.bi-bricks::before { content: "\f1ca"; } +.bi-briefcase-fill::before { content: "\f1cb"; } +.bi-briefcase::before { content: "\f1cc"; } +.bi-brightness-alt-high-fill::before { content: "\f1cd"; } +.bi-brightness-alt-high::before { content: "\f1ce"; } +.bi-brightness-alt-low-fill::before { content: "\f1cf"; } +.bi-brightness-alt-low::before { content: "\f1d0"; } +.bi-brightness-high-fill::before { content: "\f1d1"; } +.bi-brightness-high::before { content: "\f1d2"; } +.bi-brightness-low-fill::before { content: "\f1d3"; } +.bi-brightness-low::before { content: "\f1d4"; } +.bi-broadcast-pin::before { content: "\f1d5"; } +.bi-broadcast::before { content: "\f1d6"; } +.bi-brush-fill::before { content: "\f1d7"; } +.bi-brush::before { content: "\f1d8"; } +.bi-bucket-fill::before { content: "\f1d9"; } +.bi-bucket::before { content: "\f1da"; } +.bi-bug-fill::before { content: "\f1db"; } +.bi-bug::before { content: "\f1dc"; } +.bi-building::before { content: "\f1dd"; } +.bi-bullseye::before { content: "\f1de"; } +.bi-calculator-fill::before { content: "\f1df"; } +.bi-calculator::before { content: "\f1e0"; } +.bi-calendar-check-fill::before { content: "\f1e1"; } +.bi-calendar-check::before { content: "\f1e2"; } +.bi-calendar-date-fill::before { content: "\f1e3"; } +.bi-calendar-date::before { content: "\f1e4"; } +.bi-calendar-day-fill::before { content: "\f1e5"; } +.bi-calendar-day::before { content: "\f1e6"; } +.bi-calendar-event-fill::before { content: "\f1e7"; } +.bi-calendar-event::before { content: "\f1e8"; } +.bi-calendar-fill::before { content: "\f1e9"; } +.bi-calendar-minus-fill::before { content: "\f1ea"; } +.bi-calendar-minus::before { content: "\f1eb"; } +.bi-calendar-month-fill::before { content: "\f1ec"; } +.bi-calendar-month::before { content: "\f1ed"; } +.bi-calendar-plus-fill::before { content: "\f1ee"; } +.bi-calendar-plus::before { content: "\f1ef"; } +.bi-calendar-range-fill::before { content: "\f1f0"; } +.bi-calendar-range::before { content: "\f1f1"; } +.bi-calendar-week-fill::before { content: "\f1f2"; } +.bi-calendar-week::before { content: "\f1f3"; } +.bi-calendar-x-fill::before { content: "\f1f4"; } +.bi-calendar-x::before { content: "\f1f5"; } +.bi-calendar::before { content: "\f1f6"; } +.bi-calendar2-check-fill::before { content: "\f1f7"; } +.bi-calendar2-check::before { content: "\f1f8"; } +.bi-calendar2-date-fill::before { content: "\f1f9"; } +.bi-calendar2-date::before { content: "\f1fa"; } +.bi-calendar2-day-fill::before { content: "\f1fb"; } +.bi-calendar2-day::before { content: "\f1fc"; } +.bi-calendar2-event-fill::before { content: "\f1fd"; } +.bi-calendar2-event::before { content: "\f1fe"; } +.bi-calendar2-fill::before { content: "\f1ff"; } +.bi-calendar2-minus-fill::before { content: "\f200"; } +.bi-calendar2-minus::before { content: "\f201"; } +.bi-calendar2-month-fill::before { content: "\f202"; } +.bi-calendar2-month::before { content: "\f203"; } +.bi-calendar2-plus-fill::before { content: "\f204"; } +.bi-calendar2-plus::before { content: "\f205"; } +.bi-calendar2-range-fill::before { content: "\f206"; } +.bi-calendar2-range::before { content: "\f207"; } +.bi-calendar2-week-fill::before { content: "\f208"; } +.bi-calendar2-week::before { content: "\f209"; } +.bi-calendar2-x-fill::before { content: "\f20a"; } +.bi-calendar2-x::before { content: "\f20b"; } +.bi-calendar2::before { content: "\f20c"; } +.bi-calendar3-event-fill::before { content: "\f20d"; } +.bi-calendar3-event::before { content: "\f20e"; } +.bi-calendar3-fill::before { content: "\f20f"; } +.bi-calendar3-range-fill::before { content: "\f210"; } +.bi-calendar3-range::before { content: "\f211"; } +.bi-calendar3-week-fill::before { content: "\f212"; } +.bi-calendar3-week::before { content: "\f213"; } +.bi-calendar3::before { content: "\f214"; } +.bi-calendar4-event::before { content: "\f215"; } +.bi-calendar4-range::before { content: "\f216"; } +.bi-calendar4-week::before { content: "\f217"; } +.bi-calendar4::before { content: "\f218"; } +.bi-camera-fill::before { content: "\f219"; } +.bi-camera-reels-fill::before { content: "\f21a"; } +.bi-camera-reels::before { content: "\f21b"; } +.bi-camera-video-fill::before { content: "\f21c"; } +.bi-camera-video-off-fill::before { content: "\f21d"; } +.bi-camera-video-off::before { content: "\f21e"; } +.bi-camera-video::before { content: "\f21f"; } +.bi-camera::before { content: "\f220"; } +.bi-camera2::before { content: "\f221"; } +.bi-capslock-fill::before { content: "\f222"; } +.bi-capslock::before { content: "\f223"; } +.bi-card-checklist::before { content: "\f224"; } +.bi-card-heading::before { content: "\f225"; } +.bi-card-image::before { content: "\f226"; } +.bi-card-list::before { content: "\f227"; } +.bi-card-text::before { content: "\f228"; } +.bi-caret-down-fill::before { content: "\f229"; } +.bi-caret-down-square-fill::before { content: "\f22a"; } +.bi-caret-down-square::before { content: "\f22b"; } +.bi-caret-down::before { content: "\f22c"; } +.bi-caret-left-fill::before { content: "\f22d"; } +.bi-caret-left-square-fill::before { content: "\f22e"; } +.bi-caret-left-square::before { content: "\f22f"; } +.bi-caret-left::before { content: "\f230"; } +.bi-caret-right-fill::before { content: "\f231"; } +.bi-caret-right-square-fill::before { content: "\f232"; } +.bi-caret-right-square::before { content: "\f233"; } +.bi-caret-right::before { content: "\f234"; } +.bi-caret-up-fill::before { content: "\f235"; } +.bi-caret-up-square-fill::before { content: "\f236"; } +.bi-caret-up-square::before { content: "\f237"; } +.bi-caret-up::before { content: "\f238"; } +.bi-cart-check-fill::before { content: "\f239"; } +.bi-cart-check::before { content: "\f23a"; } +.bi-cart-dash-fill::before { content: "\f23b"; } +.bi-cart-dash::before { content: "\f23c"; } +.bi-cart-fill::before { content: "\f23d"; } +.bi-cart-plus-fill::before { content: "\f23e"; } +.bi-cart-plus::before { content: "\f23f"; } +.bi-cart-x-fill::before { content: "\f240"; } +.bi-cart-x::before { content: "\f241"; } +.bi-cart::before { content: "\f242"; } +.bi-cart2::before { content: "\f243"; } +.bi-cart3::before { content: "\f244"; } +.bi-cart4::before { content: "\f245"; } +.bi-cash-stack::before { content: "\f246"; } +.bi-cash::before { content: "\f247"; } +.bi-cast::before { content: "\f248"; } +.bi-chat-dots-fill::before { content: "\f249"; } +.bi-chat-dots::before { content: "\f24a"; } +.bi-chat-fill::before { content: "\f24b"; } +.bi-chat-left-dots-fill::before { content: "\f24c"; } +.bi-chat-left-dots::before { content: "\f24d"; } +.bi-chat-left-fill::before { content: "\f24e"; } +.bi-chat-left-quote-fill::before { content: "\f24f"; } +.bi-chat-left-quote::before { content: "\f250"; } +.bi-chat-left-text-fill::before { content: "\f251"; } +.bi-chat-left-text::before { content: "\f252"; } +.bi-chat-left::before { content: "\f253"; } +.bi-chat-quote-fill::before { content: "\f254"; } +.bi-chat-quote::before { content: "\f255"; } +.bi-chat-right-dots-fill::before { content: "\f256"; } +.bi-chat-right-dots::before { content: "\f257"; } +.bi-chat-right-fill::before { content: "\f258"; } +.bi-chat-right-quote-fill::before { content: "\f259"; } +.bi-chat-right-quote::before { content: "\f25a"; } +.bi-chat-right-text-fill::before { content: "\f25b"; } +.bi-chat-right-text::before { content: "\f25c"; } +.bi-chat-right::before { content: "\f25d"; } +.bi-chat-square-dots-fill::before { content: "\f25e"; } +.bi-chat-square-dots::before { content: "\f25f"; } +.bi-chat-square-fill::before { content: "\f260"; } +.bi-chat-square-quote-fill::before { content: "\f261"; } +.bi-chat-square-quote::before { content: "\f262"; } +.bi-chat-square-text-fill::before { content: "\f263"; } +.bi-chat-square-text::before { content: "\f264"; } +.bi-chat-square::before { content: "\f265"; } +.bi-chat-text-fill::before { content: "\f266"; } +.bi-chat-text::before { content: "\f267"; } +.bi-chat::before { content: "\f268"; } +.bi-check-all::before { content: "\f269"; } +.bi-check-circle-fill::before { content: "\f26a"; } +.bi-check-circle::before { content: "\f26b"; } +.bi-check-square-fill::before { content: "\f26c"; } +.bi-check-square::before { content: "\f26d"; } +.bi-check::before { content: "\f26e"; } +.bi-check2-all::before { content: "\f26f"; } +.bi-check2-circle::before { content: "\f270"; } +.bi-check2-square::before { content: "\f271"; } +.bi-check2::before { content: "\f272"; } +.bi-chevron-bar-contract::before { content: "\f273"; } +.bi-chevron-bar-down::before { content: "\f274"; } +.bi-chevron-bar-expand::before { content: "\f275"; } +.bi-chevron-bar-left::before { content: "\f276"; } +.bi-chevron-bar-right::before { content: "\f277"; } +.bi-chevron-bar-up::before { content: "\f278"; } +.bi-chevron-compact-down::before { content: "\f279"; } +.bi-chevron-compact-left::before { content: "\f27a"; } +.bi-chevron-compact-right::before { content: "\f27b"; } +.bi-chevron-compact-up::before { content: "\f27c"; } +.bi-chevron-contract::before { content: "\f27d"; } +.bi-chevron-double-down::before { content: "\f27e"; } +.bi-chevron-double-left::before { content: "\f27f"; } +.bi-chevron-double-right::before { content: "\f280"; } +.bi-chevron-double-up::before { content: "\f281"; } +.bi-chevron-down::before { content: "\f282"; } +.bi-chevron-expand::before { content: "\f283"; } +.bi-chevron-left::before { content: "\f284"; } +.bi-chevron-right::before { content: "\f285"; } +.bi-chevron-up::before { content: "\f286"; } +.bi-circle-fill::before { content: "\f287"; } +.bi-circle-half::before { content: "\f288"; } +.bi-circle-square::before { content: "\f289"; } +.bi-circle::before { content: "\f28a"; } +.bi-clipboard-check::before { content: "\f28b"; } +.bi-clipboard-data::before { content: "\f28c"; } +.bi-clipboard-minus::before { content: "\f28d"; } +.bi-clipboard-plus::before { content: "\f28e"; } +.bi-clipboard-x::before { content: "\f28f"; } +.bi-clipboard::before { content: "\f290"; } +.bi-clock-fill::before { content: "\f291"; } +.bi-clock-history::before { content: "\f292"; } +.bi-clock::before { content: "\f293"; } +.bi-cloud-arrow-down-fill::before { content: "\f294"; } +.bi-cloud-arrow-down::before { content: "\f295"; } +.bi-cloud-arrow-up-fill::before { content: "\f296"; } +.bi-cloud-arrow-up::before { content: "\f297"; } +.bi-cloud-check-fill::before { content: "\f298"; } +.bi-cloud-check::before { content: "\f299"; } +.bi-cloud-download-fill::before { content: "\f29a"; } +.bi-cloud-download::before { content: "\f29b"; } +.bi-cloud-drizzle-fill::before { content: "\f29c"; } +.bi-cloud-drizzle::before { content: "\f29d"; } +.bi-cloud-fill::before { content: "\f29e"; } +.bi-cloud-fog-fill::before { content: "\f29f"; } +.bi-cloud-fog::before { content: "\f2a0"; } +.bi-cloud-fog2-fill::before { content: "\f2a1"; } +.bi-cloud-fog2::before { content: "\f2a2"; } +.bi-cloud-hail-fill::before { content: "\f2a3"; } +.bi-cloud-hail::before { content: "\f2a4"; } +.bi-cloud-haze-1::before { content: "\f2a5"; } +.bi-cloud-haze-fill::before { content: "\f2a6"; } +.bi-cloud-haze::before { content: "\f2a7"; } +.bi-cloud-haze2-fill::before { content: "\f2a8"; } +.bi-cloud-lightning-fill::before { content: "\f2a9"; } +.bi-cloud-lightning-rain-fill::before { content: "\f2aa"; } +.bi-cloud-lightning-rain::before { content: "\f2ab"; } +.bi-cloud-lightning::before { content: "\f2ac"; } +.bi-cloud-minus-fill::before { content: "\f2ad"; } +.bi-cloud-minus::before { content: "\f2ae"; } +.bi-cloud-moon-fill::before { content: "\f2af"; } +.bi-cloud-moon::before { content: "\f2b0"; } +.bi-cloud-plus-fill::before { content: "\f2b1"; } +.bi-cloud-plus::before { content: "\f2b2"; } +.bi-cloud-rain-fill::before { content: "\f2b3"; } +.bi-cloud-rain-heavy-fill::before { content: "\f2b4"; } +.bi-cloud-rain-heavy::before { content: "\f2b5"; } +.bi-cloud-rain::before { content: "\f2b6"; } +.bi-cloud-slash-fill::before { content: "\f2b7"; } +.bi-cloud-slash::before { content: "\f2b8"; } +.bi-cloud-sleet-fill::before { content: "\f2b9"; } +.bi-cloud-sleet::before { content: "\f2ba"; } +.bi-cloud-snow-fill::before { content: "\f2bb"; } +.bi-cloud-snow::before { content: "\f2bc"; } +.bi-cloud-sun-fill::before { content: "\f2bd"; } +.bi-cloud-sun::before { content: "\f2be"; } +.bi-cloud-upload-fill::before { content: "\f2bf"; } +.bi-cloud-upload::before { content: "\f2c0"; } +.bi-cloud::before { content: "\f2c1"; } +.bi-clouds-fill::before { content: "\f2c2"; } +.bi-clouds::before { content: "\f2c3"; } +.bi-cloudy-fill::before { content: "\f2c4"; } +.bi-cloudy::before { content: "\f2c5"; } +.bi-code-slash::before { content: "\f2c6"; } +.bi-code-square::before { content: "\f2c7"; } +.bi-code::before { content: "\f2c8"; } +.bi-collection-fill::before { content: "\f2c9"; } +.bi-collection-play-fill::before { content: "\f2ca"; } +.bi-collection-play::before { content: "\f2cb"; } +.bi-collection::before { content: "\f2cc"; } +.bi-columns-gap::before { content: "\f2cd"; } +.bi-columns::before { content: "\f2ce"; } +.bi-command::before { content: "\f2cf"; } +.bi-compass-fill::before { content: "\f2d0"; } +.bi-compass::before { content: "\f2d1"; } +.bi-cone-striped::before { content: "\f2d2"; } +.bi-cone::before { content: "\f2d3"; } +.bi-controller::before { content: "\f2d4"; } +.bi-cpu-fill::before { content: "\f2d5"; } +.bi-cpu::before { content: "\f2d6"; } +.bi-credit-card-2-back-fill::before { content: "\f2d7"; } +.bi-credit-card-2-back::before { content: "\f2d8"; } +.bi-credit-card-2-front-fill::before { content: "\f2d9"; } +.bi-credit-card-2-front::before { content: "\f2da"; } +.bi-credit-card-fill::before { content: "\f2db"; } +.bi-credit-card::before { content: "\f2dc"; } +.bi-crop::before { content: "\f2dd"; } +.bi-cup-fill::before { content: "\f2de"; } +.bi-cup-straw::before { content: "\f2df"; } +.bi-cup::before { content: "\f2e0"; } +.bi-cursor-fill::before { content: "\f2e1"; } +.bi-cursor-text::before { content: "\f2e2"; } +.bi-cursor::before { content: "\f2e3"; } +.bi-dash-circle-dotted::before { content: "\f2e4"; } +.bi-dash-circle-fill::before { content: "\f2e5"; } +.bi-dash-circle::before { content: "\f2e6"; } +.bi-dash-square-dotted::before { content: "\f2e7"; } +.bi-dash-square-fill::before { content: "\f2e8"; } +.bi-dash-square::before { content: "\f2e9"; } +.bi-dash::before { content: "\f2ea"; } +.bi-diagram-2-fill::before { content: "\f2eb"; } +.bi-diagram-2::before { content: "\f2ec"; } +.bi-diagram-3-fill::before { content: "\f2ed"; } +.bi-diagram-3::before { content: "\f2ee"; } +.bi-diamond-fill::before { content: "\f2ef"; } +.bi-diamond-half::before { content: "\f2f0"; } +.bi-diamond::before { content: "\f2f1"; } +.bi-dice-1-fill::before { content: "\f2f2"; } +.bi-dice-1::before { content: "\f2f3"; } +.bi-dice-2-fill::before { content: "\f2f4"; } +.bi-dice-2::before { content: "\f2f5"; } +.bi-dice-3-fill::before { content: "\f2f6"; } +.bi-dice-3::before { content: "\f2f7"; } +.bi-dice-4-fill::before { content: "\f2f8"; } +.bi-dice-4::before { content: "\f2f9"; } +.bi-dice-5-fill::before { content: "\f2fa"; } +.bi-dice-5::before { content: "\f2fb"; } +.bi-dice-6-fill::before { content: "\f2fc"; } +.bi-dice-6::before { content: "\f2fd"; } +.bi-disc-fill::before { content: "\f2fe"; } +.bi-disc::before { content: "\f2ff"; } +.bi-discord::before { content: "\f300"; } +.bi-display-fill::before { content: "\f301"; } +.bi-display::before { content: "\f302"; } +.bi-distribute-horizontal::before { content: "\f303"; } +.bi-distribute-vertical::before { content: "\f304"; } +.bi-door-closed-fill::before { content: "\f305"; } +.bi-door-closed::before { content: "\f306"; } +.bi-door-open-fill::before { content: "\f307"; } +.bi-door-open::before { content: "\f308"; } +.bi-dot::before { content: "\f309"; } +.bi-download::before { content: "\f30a"; } +.bi-droplet-fill::before { content: "\f30b"; } +.bi-droplet-half::before { content: "\f30c"; } +.bi-droplet::before { content: "\f30d"; } +.bi-earbuds::before { content: "\f30e"; } +.bi-easel-fill::before { content: "\f30f"; } +.bi-easel::before { content: "\f310"; } +.bi-egg-fill::before { content: "\f311"; } +.bi-egg-fried::before { content: "\f312"; } +.bi-egg::before { content: "\f313"; } +.bi-eject-fill::before { content: "\f314"; } +.bi-eject::before { content: "\f315"; } +.bi-emoji-angry-fill::before { content: "\f316"; } +.bi-emoji-angry::before { content: "\f317"; } +.bi-emoji-dizzy-fill::before { content: "\f318"; } +.bi-emoji-dizzy::before { content: "\f319"; } +.bi-emoji-expressionless-fill::before { content: "\f31a"; } +.bi-emoji-expressionless::before { content: "\f31b"; } +.bi-emoji-frown-fill::before { content: "\f31c"; } +.bi-emoji-frown::before { content: "\f31d"; } +.bi-emoji-heart-eyes-fill::before { content: "\f31e"; } +.bi-emoji-heart-eyes::before { content: "\f31f"; } +.bi-emoji-laughing-fill::before { content: "\f320"; } +.bi-emoji-laughing::before { content: "\f321"; } +.bi-emoji-neutral-fill::before { content: "\f322"; } +.bi-emoji-neutral::before { content: "\f323"; } +.bi-emoji-smile-fill::before { content: "\f324"; } +.bi-emoji-smile-upside-down-fill::before { content: "\f325"; } +.bi-emoji-smile-upside-down::before { content: "\f326"; } +.bi-emoji-smile::before { content: "\f327"; } +.bi-emoji-sunglasses-fill::before { content: "\f328"; } +.bi-emoji-sunglasses::before { content: "\f329"; } +.bi-emoji-wink-fill::before { content: "\f32a"; } +.bi-emoji-wink::before { content: "\f32b"; } +.bi-envelope-fill::before { content: "\f32c"; } +.bi-envelope-open-fill::before { content: "\f32d"; } +.bi-envelope-open::before { content: "\f32e"; } +.bi-envelope::before { content: "\f32f"; } +.bi-eraser-fill::before { content: "\f330"; } +.bi-eraser::before { content: "\f331"; } +.bi-exclamation-circle-fill::before { content: "\f332"; } +.bi-exclamation-circle::before { content: "\f333"; } +.bi-exclamation-diamond-fill::before { content: "\f334"; } +.bi-exclamation-diamond::before { content: "\f335"; } +.bi-exclamation-octagon-fill::before { content: "\f336"; } +.bi-exclamation-octagon::before { content: "\f337"; } +.bi-exclamation-square-fill::before { content: "\f338"; } +.bi-exclamation-square::before { content: "\f339"; } +.bi-exclamation-triangle-fill::before { content: "\f33a"; } +.bi-exclamation-triangle::before { content: "\f33b"; } +.bi-exclamation::before { content: "\f33c"; } +.bi-exclude::before { content: "\f33d"; } +.bi-eye-fill::before { content: "\f33e"; } +.bi-eye-slash-fill::before { content: "\f33f"; } +.bi-eye-slash::before { content: "\f340"; } +.bi-eye::before { content: "\f341"; } +.bi-eyedropper::before { content: "\f342"; } +.bi-eyeglasses::before { content: "\f343"; } +.bi-facebook::before { content: "\f344"; } +.bi-file-arrow-down-fill::before { content: "\f345"; } +.bi-file-arrow-down::before { content: "\f346"; } +.bi-file-arrow-up-fill::before { content: "\f347"; } +.bi-file-arrow-up::before { content: "\f348"; } +.bi-file-bar-graph-fill::before { content: "\f349"; } +.bi-file-bar-graph::before { content: "\f34a"; } +.bi-file-binary-fill::before { content: "\f34b"; } +.bi-file-binary::before { content: "\f34c"; } +.bi-file-break-fill::before { content: "\f34d"; } +.bi-file-break::before { content: "\f34e"; } +.bi-file-check-fill::before { content: "\f34f"; } +.bi-file-check::before { content: "\f350"; } +.bi-file-code-fill::before { content: "\f351"; } +.bi-file-code::before { content: "\f352"; } +.bi-file-diff-fill::before { content: "\f353"; } +.bi-file-diff::before { content: "\f354"; } +.bi-file-earmark-arrow-down-fill::before { content: "\f355"; } +.bi-file-earmark-arrow-down::before { content: "\f356"; } +.bi-file-earmark-arrow-up-fill::before { content: "\f357"; } +.bi-file-earmark-arrow-up::before { content: "\f358"; } +.bi-file-earmark-bar-graph-fill::before { content: "\f359"; } +.bi-file-earmark-bar-graph::before { content: "\f35a"; } +.bi-file-earmark-binary-fill::before { content: "\f35b"; } +.bi-file-earmark-binary::before { content: "\f35c"; } +.bi-file-earmark-break-fill::before { content: "\f35d"; } +.bi-file-earmark-break::before { content: "\f35e"; } +.bi-file-earmark-check-fill::before { content: "\f35f"; } +.bi-file-earmark-check::before { content: "\f360"; } +.bi-file-earmark-code-fill::before { content: "\f361"; } +.bi-file-earmark-code::before { content: "\f362"; } +.bi-file-earmark-diff-fill::before { content: "\f363"; } +.bi-file-earmark-diff::before { content: "\f364"; } +.bi-file-earmark-easel-fill::before { content: "\f365"; } +.bi-file-earmark-easel::before { content: "\f366"; } +.bi-file-earmark-excel-fill::before { content: "\f367"; } +.bi-file-earmark-excel::before { content: "\f368"; } +.bi-file-earmark-fill::before { content: "\f369"; } +.bi-file-earmark-font-fill::before { content: "\f36a"; } +.bi-file-earmark-font::before { content: "\f36b"; } +.bi-file-earmark-image-fill::before { content: "\f36c"; } +.bi-file-earmark-image::before { content: "\f36d"; } +.bi-file-earmark-lock-fill::before { content: "\f36e"; } +.bi-file-earmark-lock::before { content: "\f36f"; } +.bi-file-earmark-lock2-fill::before { content: "\f370"; } +.bi-file-earmark-lock2::before { content: "\f371"; } +.bi-file-earmark-medical-fill::before { content: "\f372"; } +.bi-file-earmark-medical::before { content: "\f373"; } +.bi-file-earmark-minus-fill::before { content: "\f374"; } +.bi-file-earmark-minus::before { content: "\f375"; } +.bi-file-earmark-music-fill::before { content: "\f376"; } +.bi-file-earmark-music::before { content: "\f377"; } +.bi-file-earmark-person-fill::before { content: "\f378"; } +.bi-file-earmark-person::before { content: "\f379"; } +.bi-file-earmark-play-fill::before { content: "\f37a"; } +.bi-file-earmark-play::before { content: "\f37b"; } +.bi-file-earmark-plus-fill::before { content: "\f37c"; } +.bi-file-earmark-plus::before { content: "\f37d"; } +.bi-file-earmark-post-fill::before { content: "\f37e"; } +.bi-file-earmark-post::before { content: "\f37f"; } +.bi-file-earmark-ppt-fill::before { content: "\f380"; } +.bi-file-earmark-ppt::before { content: "\f381"; } +.bi-file-earmark-richtext-fill::before { content: "\f382"; } +.bi-file-earmark-richtext::before { content: "\f383"; } +.bi-file-earmark-ruled-fill::before { content: "\f384"; } +.bi-file-earmark-ruled::before { content: "\f385"; } +.bi-file-earmark-slides-fill::before { content: "\f386"; } +.bi-file-earmark-slides::before { content: "\f387"; } +.bi-file-earmark-spreadsheet-fill::before { content: "\f388"; } +.bi-file-earmark-spreadsheet::before { content: "\f389"; } +.bi-file-earmark-text-fill::before { content: "\f38a"; } +.bi-file-earmark-text::before { content: "\f38b"; } +.bi-file-earmark-word-fill::before { content: "\f38c"; } +.bi-file-earmark-word::before { content: "\f38d"; } +.bi-file-earmark-x-fill::before { content: "\f38e"; } +.bi-file-earmark-x::before { content: "\f38f"; } +.bi-file-earmark-zip-fill::before { content: "\f390"; } +.bi-file-earmark-zip::before { content: "\f391"; } +.bi-file-earmark::before { content: "\f392"; } +.bi-file-easel-fill::before { content: "\f393"; } +.bi-file-easel::before { content: "\f394"; } +.bi-file-excel-fill::before { content: "\f395"; } +.bi-file-excel::before { content: "\f396"; } +.bi-file-fill::before { content: "\f397"; } +.bi-file-font-fill::before { content: "\f398"; } +.bi-file-font::before { content: "\f399"; } +.bi-file-image-fill::before { content: "\f39a"; } +.bi-file-image::before { content: "\f39b"; } +.bi-file-lock-fill::before { content: "\f39c"; } +.bi-file-lock::before { content: "\f39d"; } +.bi-file-lock2-fill::before { content: "\f39e"; } +.bi-file-lock2::before { content: "\f39f"; } +.bi-file-medical-fill::before { content: "\f3a0"; } +.bi-file-medical::before { content: "\f3a1"; } +.bi-file-minus-fill::before { content: "\f3a2"; } +.bi-file-minus::before { content: "\f3a3"; } +.bi-file-music-fill::before { content: "\f3a4"; } +.bi-file-music::before { content: "\f3a5"; } +.bi-file-person-fill::before { content: "\f3a6"; } +.bi-file-person::before { content: "\f3a7"; } +.bi-file-play-fill::before { content: "\f3a8"; } +.bi-file-play::before { content: "\f3a9"; } +.bi-file-plus-fill::before { content: "\f3aa"; } +.bi-file-plus::before { content: "\f3ab"; } +.bi-file-post-fill::before { content: "\f3ac"; } +.bi-file-post::before { content: "\f3ad"; } +.bi-file-ppt-fill::before { content: "\f3ae"; } +.bi-file-ppt::before { content: "\f3af"; } +.bi-file-richtext-fill::before { content: "\f3b0"; } +.bi-file-richtext::before { content: "\f3b1"; } +.bi-file-ruled-fill::before { content: "\f3b2"; } +.bi-file-ruled::before { content: "\f3b3"; } +.bi-file-slides-fill::before { content: "\f3b4"; } +.bi-file-slides::before { content: "\f3b5"; } +.bi-file-spreadsheet-fill::before { content: "\f3b6"; } +.bi-file-spreadsheet::before { content: "\f3b7"; } +.bi-file-text-fill::before { content: "\f3b8"; } +.bi-file-text::before { content: "\f3b9"; } +.bi-file-word-fill::before { content: "\f3ba"; } +.bi-file-word::before { content: "\f3bb"; } +.bi-file-x-fill::before { content: "\f3bc"; } +.bi-file-x::before { content: "\f3bd"; } +.bi-file-zip-fill::before { content: "\f3be"; } +.bi-file-zip::before { content: "\f3bf"; } +.bi-file::before { content: "\f3c0"; } +.bi-files-alt::before { content: "\f3c1"; } +.bi-files::before { content: "\f3c2"; } +.bi-film::before { content: "\f3c3"; } +.bi-filter-circle-fill::before { content: "\f3c4"; } +.bi-filter-circle::before { content: "\f3c5"; } +.bi-filter-left::before { content: "\f3c6"; } +.bi-filter-right::before { content: "\f3c7"; } +.bi-filter-square-fill::before { content: "\f3c8"; } +.bi-filter-square::before { content: "\f3c9"; } +.bi-filter::before { content: "\f3ca"; } +.bi-flag-fill::before { content: "\f3cb"; } +.bi-flag::before { content: "\f3cc"; } +.bi-flower1::before { content: "\f3cd"; } +.bi-flower2::before { content: "\f3ce"; } +.bi-flower3::before { content: "\f3cf"; } +.bi-folder-check::before { content: "\f3d0"; } +.bi-folder-fill::before { content: "\f3d1"; } +.bi-folder-minus::before { content: "\f3d2"; } +.bi-folder-plus::before { content: "\f3d3"; } +.bi-folder-symlink-fill::before { content: "\f3d4"; } +.bi-folder-symlink::before { content: "\f3d5"; } +.bi-folder-x::before { content: "\f3d6"; } +.bi-folder::before { content: "\f3d7"; } +.bi-folder2-open::before { content: "\f3d8"; } +.bi-folder2::before { content: "\f3d9"; } +.bi-fonts::before { content: "\f3da"; } +.bi-forward-fill::before { content: "\f3db"; } +.bi-forward::before { content: "\f3dc"; } +.bi-front::before { content: "\f3dd"; } +.bi-fullscreen-exit::before { content: "\f3de"; } +.bi-fullscreen::before { content: "\f3df"; } +.bi-funnel-fill::before { content: "\f3e0"; } +.bi-funnel::before { content: "\f3e1"; } +.bi-gear-fill::before { content: "\f3e2"; } +.bi-gear-wide-connected::before { content: "\f3e3"; } +.bi-gear-wide::before { content: "\f3e4"; } +.bi-gear::before { content: "\f3e5"; } +.bi-gem::before { content: "\f3e6"; } +.bi-geo-alt-fill::before { content: "\f3e7"; } +.bi-geo-alt::before { content: "\f3e8"; } +.bi-geo-fill::before { content: "\f3e9"; } +.bi-geo::before { content: "\f3ea"; } +.bi-gift-fill::before { content: "\f3eb"; } +.bi-gift::before { content: "\f3ec"; } +.bi-github::before { content: "\f3ed"; } +.bi-globe::before { content: "\f3ee"; } +.bi-globe2::before { content: "\f3ef"; } +.bi-google::before { content: "\f3f0"; } +.bi-graph-down::before { content: "\f3f1"; } +.bi-graph-up::before { content: "\f3f2"; } +.bi-grid-1x2-fill::before { content: "\f3f3"; } +.bi-grid-1x2::before { content: "\f3f4"; } +.bi-grid-3x2-gap-fill::before { content: "\f3f5"; } +.bi-grid-3x2-gap::before { content: "\f3f6"; } +.bi-grid-3x2::before { content: "\f3f7"; } +.bi-grid-3x3-gap-fill::before { content: "\f3f8"; } +.bi-grid-3x3-gap::before { content: "\f3f9"; } +.bi-grid-3x3::before { content: "\f3fa"; } +.bi-grid-fill::before { content: "\f3fb"; } +.bi-grid::before { content: "\f3fc"; } +.bi-grip-horizontal::before { content: "\f3fd"; } +.bi-grip-vertical::before { content: "\f3fe"; } +.bi-hammer::before { content: "\f3ff"; } +.bi-hand-index-fill::before { content: "\f400"; } +.bi-hand-index-thumb-fill::before { content: "\f401"; } +.bi-hand-index-thumb::before { content: "\f402"; } +.bi-hand-index::before { content: "\f403"; } +.bi-hand-thumbs-down-fill::before { content: "\f404"; } +.bi-hand-thumbs-down::before { content: "\f405"; } +.bi-hand-thumbs-up-fill::before { content: "\f406"; } +.bi-hand-thumbs-up::before { content: "\f407"; } +.bi-handbag-fill::before { content: "\f408"; } +.bi-handbag::before { content: "\f409"; } +.bi-hash::before { content: "\f40a"; } +.bi-hdd-fill::before { content: "\f40b"; } +.bi-hdd-network-fill::before { content: "\f40c"; } +.bi-hdd-network::before { content: "\f40d"; } +.bi-hdd-rack-fill::before { content: "\f40e"; } +.bi-hdd-rack::before { content: "\f40f"; } +.bi-hdd-stack-fill::before { content: "\f410"; } +.bi-hdd-stack::before { content: "\f411"; } +.bi-hdd::before { content: "\f412"; } +.bi-headphones::before { content: "\f413"; } +.bi-headset::before { content: "\f414"; } +.bi-heart-fill::before { content: "\f415"; } +.bi-heart-half::before { content: "\f416"; } +.bi-heart::before { content: "\f417"; } +.bi-heptagon-fill::before { content: "\f418"; } +.bi-heptagon-half::before { content: "\f419"; } +.bi-heptagon::before { content: "\f41a"; } +.bi-hexagon-fill::before { content: "\f41b"; } +.bi-hexagon-half::before { content: "\f41c"; } +.bi-hexagon::before { content: "\f41d"; } +.bi-hourglass-bottom::before { content: "\f41e"; } +.bi-hourglass-split::before { content: "\f41f"; } +.bi-hourglass-top::before { content: "\f420"; } +.bi-hourglass::before { content: "\f421"; } +.bi-house-door-fill::before { content: "\f422"; } +.bi-house-door::before { content: "\f423"; } +.bi-house-fill::before { content: "\f424"; } +.bi-house::before { content: "\f425"; } +.bi-hr::before { content: "\f426"; } +.bi-hurricane::before { content: "\f427"; } +.bi-image-alt::before { content: "\f428"; } +.bi-image-fill::before { content: "\f429"; } +.bi-image::before { content: "\f42a"; } +.bi-images::before { content: "\f42b"; } +.bi-inbox-fill::before { content: "\f42c"; } +.bi-inbox::before { content: "\f42d"; } +.bi-inboxes-fill::before { content: "\f42e"; } +.bi-inboxes::before { content: "\f42f"; } +.bi-info-circle-fill::before { content: "\f430"; } +.bi-info-circle::before { content: "\f431"; } +.bi-info-square-fill::before { content: "\f432"; } +.bi-info-square::before { content: "\f433"; } +.bi-info::before { content: "\f434"; } +.bi-input-cursor-text::before { content: "\f435"; } +.bi-input-cursor::before { content: "\f436"; } +.bi-instagram::before { content: "\f437"; } +.bi-intersect::before { content: "\f438"; } +.bi-journal-album::before { content: "\f439"; } +.bi-journal-arrow-down::before { content: "\f43a"; } +.bi-journal-arrow-up::before { content: "\f43b"; } +.bi-journal-bookmark-fill::before { content: "\f43c"; } +.bi-journal-bookmark::before { content: "\f43d"; } +.bi-journal-check::before { content: "\f43e"; } +.bi-journal-code::before { content: "\f43f"; } +.bi-journal-medical::before { content: "\f440"; } +.bi-journal-minus::before { content: "\f441"; } +.bi-journal-plus::before { content: "\f442"; } +.bi-journal-richtext::before { content: "\f443"; } +.bi-journal-text::before { content: "\f444"; } +.bi-journal-x::before { content: "\f445"; } +.bi-journal::before { content: "\f446"; } +.bi-journals::before { content: "\f447"; } +.bi-joystick::before { content: "\f448"; } +.bi-justify-left::before { content: "\f449"; } +.bi-justify-right::before { content: "\f44a"; } +.bi-justify::before { content: "\f44b"; } +.bi-kanban-fill::before { content: "\f44c"; } +.bi-kanban::before { content: "\f44d"; } +.bi-key-fill::before { content: "\f44e"; } +.bi-key::before { content: "\f44f"; } +.bi-keyboard-fill::before { content: "\f450"; } +.bi-keyboard::before { content: "\f451"; } +.bi-ladder::before { content: "\f452"; } +.bi-lamp-fill::before { content: "\f453"; } +.bi-lamp::before { content: "\f454"; } +.bi-laptop-fill::before { content: "\f455"; } +.bi-laptop::before { content: "\f456"; } +.bi-layer-backward::before { content: "\f457"; } +.bi-layer-forward::before { content: "\f458"; } +.bi-layers-fill::before { content: "\f459"; } +.bi-layers-half::before { content: "\f45a"; } +.bi-layers::before { content: "\f45b"; } +.bi-layout-sidebar-inset-reverse::before { content: "\f45c"; } +.bi-layout-sidebar-inset::before { content: "\f45d"; } +.bi-layout-sidebar-reverse::before { content: "\f45e"; } +.bi-layout-sidebar::before { content: "\f45f"; } +.bi-layout-split::before { content: "\f460"; } +.bi-layout-text-sidebar-reverse::before { content: "\f461"; } +.bi-layout-text-sidebar::before { content: "\f462"; } +.bi-layout-text-window-reverse::before { content: "\f463"; } +.bi-layout-text-window::before { content: "\f464"; } +.bi-layout-three-columns::before { content: "\f465"; } +.bi-layout-wtf::before { content: "\f466"; } +.bi-life-preserver::before { content: "\f467"; } +.bi-lightbulb-fill::before { content: "\f468"; } +.bi-lightbulb-off-fill::before { content: "\f469"; } +.bi-lightbulb-off::before { content: "\f46a"; } +.bi-lightbulb::before { content: "\f46b"; } +.bi-lightning-charge-fill::before { content: "\f46c"; } +.bi-lightning-charge::before { content: "\f46d"; } +.bi-lightning-fill::before { content: "\f46e"; } +.bi-lightning::before { content: "\f46f"; } +.bi-link-45deg::before { content: "\f470"; } +.bi-link::before { content: "\f471"; } +.bi-linkedin::before { content: "\f472"; } +.bi-list-check::before { content: "\f473"; } +.bi-list-nested::before { content: "\f474"; } +.bi-list-ol::before { content: "\f475"; } +.bi-list-stars::before { content: "\f476"; } +.bi-list-task::before { content: "\f477"; } +.bi-list-ul::before { content: "\f478"; } +.bi-list::before { content: "\f479"; } +.bi-lock-fill::before { content: "\f47a"; } +.bi-lock::before { content: "\f47b"; } +.bi-mailbox::before { content: "\f47c"; } +.bi-mailbox2::before { content: "\f47d"; } +.bi-map-fill::before { content: "\f47e"; } +.bi-map::before { content: "\f47f"; } +.bi-markdown-fill::before { content: "\f480"; } +.bi-markdown::before { content: "\f481"; } +.bi-mask::before { content: "\f482"; } +.bi-megaphone-fill::before { content: "\f483"; } +.bi-megaphone::before { content: "\f484"; } +.bi-menu-app-fill::before { content: "\f485"; } +.bi-menu-app::before { content: "\f486"; } +.bi-menu-button-fill::before { content: "\f487"; } +.bi-menu-button-wide-fill::before { content: "\f488"; } +.bi-menu-button-wide::before { content: "\f489"; } +.bi-menu-button::before { content: "\f48a"; } +.bi-menu-down::before { content: "\f48b"; } +.bi-menu-up::before { content: "\f48c"; } +.bi-mic-fill::before { content: "\f48d"; } +.bi-mic-mute-fill::before { content: "\f48e"; } +.bi-mic-mute::before { content: "\f48f"; } +.bi-mic::before { content: "\f490"; } +.bi-minecart-loaded::before { content: "\f491"; } +.bi-minecart::before { content: "\f492"; } +.bi-moisture::before { content: "\f493"; } +.bi-moon-fill::before { content: "\f494"; } +.bi-moon-stars-fill::before { content: "\f495"; } +.bi-moon-stars::before { content: "\f496"; } +.bi-moon::before { content: "\f497"; } +.bi-mouse-fill::before { content: "\f498"; } +.bi-mouse::before { content: "\f499"; } +.bi-mouse2-fill::before { content: "\f49a"; } +.bi-mouse2::before { content: "\f49b"; } +.bi-mouse3-fill::before { content: "\f49c"; } +.bi-mouse3::before { content: "\f49d"; } +.bi-music-note-beamed::before { content: "\f49e"; } +.bi-music-note-list::before { content: "\f49f"; } +.bi-music-note::before { content: "\f4a0"; } +.bi-music-player-fill::before { content: "\f4a1"; } +.bi-music-player::before { content: "\f4a2"; } +.bi-newspaper::before { content: "\f4a3"; } +.bi-node-minus-fill::before { content: "\f4a4"; } +.bi-node-minus::before { content: "\f4a5"; } +.bi-node-plus-fill::before { content: "\f4a6"; } +.bi-node-plus::before { content: "\f4a7"; } +.bi-nut-fill::before { content: "\f4a8"; } +.bi-nut::before { content: "\f4a9"; } +.bi-octagon-fill::before { content: "\f4aa"; } +.bi-octagon-half::before { content: "\f4ab"; } +.bi-octagon::before { content: "\f4ac"; } +.bi-option::before { content: "\f4ad"; } +.bi-outlet::before { content: "\f4ae"; } +.bi-paint-bucket::before { content: "\f4af"; } +.bi-palette-fill::before { content: "\f4b0"; } +.bi-palette::before { content: "\f4b1"; } +.bi-palette2::before { content: "\f4b2"; } +.bi-paperclip::before { content: "\f4b3"; } +.bi-paragraph::before { content: "\f4b4"; } +.bi-patch-check-fill::before { content: "\f4b5"; } +.bi-patch-check::before { content: "\f4b6"; } +.bi-patch-exclamation-fill::before { content: "\f4b7"; } +.bi-patch-exclamation::before { content: "\f4b8"; } +.bi-patch-minus-fill::before { content: "\f4b9"; } +.bi-patch-minus::before { content: "\f4ba"; } +.bi-patch-plus-fill::before { content: "\f4bb"; } +.bi-patch-plus::before { content: "\f4bc"; } +.bi-patch-question-fill::before { content: "\f4bd"; } +.bi-patch-question::before { content: "\f4be"; } +.bi-pause-btn-fill::before { content: "\f4bf"; } +.bi-pause-btn::before { content: "\f4c0"; } +.bi-pause-circle-fill::before { content: "\f4c1"; } +.bi-pause-circle::before { content: "\f4c2"; } +.bi-pause-fill::before { content: "\f4c3"; } +.bi-pause::before { content: "\f4c4"; } +.bi-peace-fill::before { content: "\f4c5"; } +.bi-peace::before { content: "\f4c6"; } +.bi-pen-fill::before { content: "\f4c7"; } +.bi-pen::before { content: "\f4c8"; } +.bi-pencil-fill::before { content: "\f4c9"; } +.bi-pencil-square::before { content: "\f4ca"; } +.bi-pencil::before { content: "\f4cb"; } +.bi-pentagon-fill::before { content: "\f4cc"; } +.bi-pentagon-half::before { content: "\f4cd"; } +.bi-pentagon::before { content: "\f4ce"; } +.bi-people-fill::before { content: "\f4cf"; } +.bi-people::before { content: "\f4d0"; } +.bi-percent::before { content: "\f4d1"; } +.bi-person-badge-fill::before { content: "\f4d2"; } +.bi-person-badge::before { content: "\f4d3"; } +.bi-person-bounding-box::before { content: "\f4d4"; } +.bi-person-check-fill::before { content: "\f4d5"; } +.bi-person-check::before { content: "\f4d6"; } +.bi-person-circle::before { content: "\f4d7"; } +.bi-person-dash-fill::before { content: "\f4d8"; } +.bi-person-dash::before { content: "\f4d9"; } +.bi-person-fill::before { content: "\f4da"; } +.bi-person-lines-fill::before { content: "\f4db"; } +.bi-person-plus-fill::before { content: "\f4dc"; } +.bi-person-plus::before { content: "\f4dd"; } +.bi-person-square::before { content: "\f4de"; } +.bi-person-x-fill::before { content: "\f4df"; } +.bi-person-x::before { content: "\f4e0"; } +.bi-person::before { content: "\f4e1"; } +.bi-phone-fill::before { content: "\f4e2"; } +.bi-phone-landscape-fill::before { content: "\f4e3"; } +.bi-phone-landscape::before { content: "\f4e4"; } +.bi-phone-vibrate-fill::before { content: "\f4e5"; } +.bi-phone-vibrate::before { content: "\f4e6"; } +.bi-phone::before { content: "\f4e7"; } +.bi-pie-chart-fill::before { content: "\f4e8"; } +.bi-pie-chart::before { content: "\f4e9"; } +.bi-pin-angle-fill::before { content: "\f4ea"; } +.bi-pin-angle::before { content: "\f4eb"; } +.bi-pin-fill::before { content: "\f4ec"; } +.bi-pin::before { content: "\f4ed"; } +.bi-pip-fill::before { content: "\f4ee"; } +.bi-pip::before { content: "\f4ef"; } +.bi-play-btn-fill::before { content: "\f4f0"; } +.bi-play-btn::before { content: "\f4f1"; } +.bi-play-circle-fill::before { content: "\f4f2"; } +.bi-play-circle::before { content: "\f4f3"; } +.bi-play-fill::before { content: "\f4f4"; } +.bi-play::before { content: "\f4f5"; } +.bi-plug-fill::before { content: "\f4f6"; } +.bi-plug::before { content: "\f4f7"; } +.bi-plus-circle-dotted::before { content: "\f4f8"; } +.bi-plus-circle-fill::before { content: "\f4f9"; } +.bi-plus-circle::before { content: "\f4fa"; } +.bi-plus-square-dotted::before { content: "\f4fb"; } +.bi-plus-square-fill::before { content: "\f4fc"; } +.bi-plus-square::before { content: "\f4fd"; } +.bi-plus::before { content: "\f4fe"; } +.bi-power::before { content: "\f4ff"; } +.bi-printer-fill::before { content: "\f500"; } +.bi-printer::before { content: "\f501"; } +.bi-puzzle-fill::before { content: "\f502"; } +.bi-puzzle::before { content: "\f503"; } +.bi-question-circle-fill::before { content: "\f504"; } +.bi-question-circle::before { content: "\f505"; } +.bi-question-diamond-fill::before { content: "\f506"; } +.bi-question-diamond::before { content: "\f507"; } +.bi-question-octagon-fill::before { content: "\f508"; } +.bi-question-octagon::before { content: "\f509"; } +.bi-question-square-fill::before { content: "\f50a"; } +.bi-question-square::before { content: "\f50b"; } +.bi-question::before { content: "\f50c"; } +.bi-rainbow::before { content: "\f50d"; } +.bi-receipt-cutoff::before { content: "\f50e"; } +.bi-receipt::before { content: "\f50f"; } +.bi-reception-0::before { content: "\f510"; } +.bi-reception-1::before { content: "\f511"; } +.bi-reception-2::before { content: "\f512"; } +.bi-reception-3::before { content: "\f513"; } +.bi-reception-4::before { content: "\f514"; } +.bi-record-btn-fill::before { content: "\f515"; } +.bi-record-btn::before { content: "\f516"; } +.bi-record-circle-fill::before { content: "\f517"; } +.bi-record-circle::before { content: "\f518"; } +.bi-record-fill::before { content: "\f519"; } +.bi-record::before { content: "\f51a"; } +.bi-record2-fill::before { content: "\f51b"; } +.bi-record2::before { content: "\f51c"; } +.bi-reply-all-fill::before { content: "\f51d"; } +.bi-reply-all::before { content: "\f51e"; } +.bi-reply-fill::before { content: "\f51f"; } +.bi-reply::before { content: "\f520"; } +.bi-rss-fill::before { content: "\f521"; } +.bi-rss::before { content: "\f522"; } +.bi-rulers::before { content: "\f523"; } +.bi-save-fill::before { content: "\f524"; } +.bi-save::before { content: "\f525"; } +.bi-save2-fill::before { content: "\f526"; } +.bi-save2::before { content: "\f527"; } +.bi-scissors::before { content: "\f528"; } +.bi-screwdriver::before { content: "\f529"; } +.bi-search::before { content: "\f52a"; } +.bi-segmented-nav::before { content: "\f52b"; } +.bi-server::before { content: "\f52c"; } +.bi-share-fill::before { content: "\f52d"; } +.bi-share::before { content: "\f52e"; } +.bi-shield-check::before { content: "\f52f"; } +.bi-shield-exclamation::before { content: "\f530"; } +.bi-shield-fill-check::before { content: "\f531"; } +.bi-shield-fill-exclamation::before { content: "\f532"; } +.bi-shield-fill-minus::before { content: "\f533"; } +.bi-shield-fill-plus::before { content: "\f534"; } +.bi-shield-fill-x::before { content: "\f535"; } +.bi-shield-fill::before { content: "\f536"; } +.bi-shield-lock-fill::before { content: "\f537"; } +.bi-shield-lock::before { content: "\f538"; } +.bi-shield-minus::before { content: "\f539"; } +.bi-shield-plus::before { content: "\f53a"; } +.bi-shield-shaded::before { content: "\f53b"; } +.bi-shield-slash-fill::before { content: "\f53c"; } +.bi-shield-slash::before { content: "\f53d"; } +.bi-shield-x::before { content: "\f53e"; } +.bi-shield::before { content: "\f53f"; } +.bi-shift-fill::before { content: "\f540"; } +.bi-shift::before { content: "\f541"; } +.bi-shop-window::before { content: "\f542"; } +.bi-shop::before { content: "\f543"; } +.bi-shuffle::before { content: "\f544"; } +.bi-signpost-2-fill::before { content: "\f545"; } +.bi-signpost-2::before { content: "\f546"; } +.bi-signpost-fill::before { content: "\f547"; } +.bi-signpost-split-fill::before { content: "\f548"; } +.bi-signpost-split::before { content: "\f549"; } +.bi-signpost::before { content: "\f54a"; } +.bi-sim-fill::before { content: "\f54b"; } +.bi-sim::before { content: "\f54c"; } +.bi-skip-backward-btn-fill::before { content: "\f54d"; } +.bi-skip-backward-btn::before { content: "\f54e"; } +.bi-skip-backward-circle-fill::before { content: "\f54f"; } +.bi-skip-backward-circle::before { content: "\f550"; } +.bi-skip-backward-fill::before { content: "\f551"; } +.bi-skip-backward::before { content: "\f552"; } +.bi-skip-end-btn-fill::before { content: "\f553"; } +.bi-skip-end-btn::before { content: "\f554"; } +.bi-skip-end-circle-fill::before { content: "\f555"; } +.bi-skip-end-circle::before { content: "\f556"; } +.bi-skip-end-fill::before { content: "\f557"; } +.bi-skip-end::before { content: "\f558"; } +.bi-skip-forward-btn-fill::before { content: "\f559"; } +.bi-skip-forward-btn::before { content: "\f55a"; } +.bi-skip-forward-circle-fill::before { content: "\f55b"; } +.bi-skip-forward-circle::before { content: "\f55c"; } +.bi-skip-forward-fill::before { content: "\f55d"; } +.bi-skip-forward::before { content: "\f55e"; } +.bi-skip-start-btn-fill::before { content: "\f55f"; } +.bi-skip-start-btn::before { content: "\f560"; } +.bi-skip-start-circle-fill::before { content: "\f561"; } +.bi-skip-start-circle::before { content: "\f562"; } +.bi-skip-start-fill::before { content: "\f563"; } +.bi-skip-start::before { content: "\f564"; } +.bi-slack::before { content: "\f565"; } +.bi-slash-circle-fill::before { content: "\f566"; } +.bi-slash-circle::before { content: "\f567"; } +.bi-slash-square-fill::before { content: "\f568"; } +.bi-slash-square::before { content: "\f569"; } +.bi-slash::before { content: "\f56a"; } +.bi-sliders::before { content: "\f56b"; } +.bi-smartwatch::before { content: "\f56c"; } +.bi-snow::before { content: "\f56d"; } +.bi-snow2::before { content: "\f56e"; } +.bi-snow3::before { content: "\f56f"; } +.bi-sort-alpha-down-alt::before { content: "\f570"; } +.bi-sort-alpha-down::before { content: "\f571"; } +.bi-sort-alpha-up-alt::before { content: "\f572"; } +.bi-sort-alpha-up::before { content: "\f573"; } +.bi-sort-down-alt::before { content: "\f574"; } +.bi-sort-down::before { content: "\f575"; } +.bi-sort-numeric-down-alt::before { content: "\f576"; } +.bi-sort-numeric-down::before { content: "\f577"; } +.bi-sort-numeric-up-alt::before { content: "\f578"; } +.bi-sort-numeric-up::before { content: "\f579"; } +.bi-sort-up-alt::before { content: "\f57a"; } +.bi-sort-up::before { content: "\f57b"; } +.bi-soundwave::before { content: "\f57c"; } +.bi-speaker-fill::before { content: "\f57d"; } +.bi-speaker::before { content: "\f57e"; } +.bi-speedometer::before { content: "\f57f"; } +.bi-speedometer2::before { content: "\f580"; } +.bi-spellcheck::before { content: "\f581"; } +.bi-square-fill::before { content: "\f582"; } +.bi-square-half::before { content: "\f583"; } +.bi-square::before { content: "\f584"; } +.bi-stack::before { content: "\f585"; } +.bi-star-fill::before { content: "\f586"; } +.bi-star-half::before { content: "\f587"; } +.bi-star::before { content: "\f588"; } +.bi-stars::before { content: "\f589"; } +.bi-stickies-fill::before { content: "\f58a"; } +.bi-stickies::before { content: "\f58b"; } +.bi-sticky-fill::before { content: "\f58c"; } +.bi-sticky::before { content: "\f58d"; } +.bi-stop-btn-fill::before { content: "\f58e"; } +.bi-stop-btn::before { content: "\f58f"; } +.bi-stop-circle-fill::before { content: "\f590"; } +.bi-stop-circle::before { content: "\f591"; } +.bi-stop-fill::before { content: "\f592"; } +.bi-stop::before { content: "\f593"; } +.bi-stoplights-fill::before { content: "\f594"; } +.bi-stoplights::before { content: "\f595"; } +.bi-stopwatch-fill::before { content: "\f596"; } +.bi-stopwatch::before { content: "\f597"; } +.bi-subtract::before { content: "\f598"; } +.bi-suit-club-fill::before { content: "\f599"; } +.bi-suit-club::before { content: "\f59a"; } +.bi-suit-diamond-fill::before { content: "\f59b"; } +.bi-suit-diamond::before { content: "\f59c"; } +.bi-suit-heart-fill::before { content: "\f59d"; } +.bi-suit-heart::before { content: "\f59e"; } +.bi-suit-spade-fill::before { content: "\f59f"; } +.bi-suit-spade::before { content: "\f5a0"; } +.bi-sun-fill::before { content: "\f5a1"; } +.bi-sun::before { content: "\f5a2"; } +.bi-sunglasses::before { content: "\f5a3"; } +.bi-sunrise-fill::before { content: "\f5a4"; } +.bi-sunrise::before { content: "\f5a5"; } +.bi-sunset-fill::before { content: "\f5a6"; } +.bi-sunset::before { content: "\f5a7"; } +.bi-symmetry-horizontal::before { content: "\f5a8"; } +.bi-symmetry-vertical::before { content: "\f5a9"; } +.bi-table::before { content: "\f5aa"; } +.bi-tablet-fill::before { content: "\f5ab"; } +.bi-tablet-landscape-fill::before { content: "\f5ac"; } +.bi-tablet-landscape::before { content: "\f5ad"; } +.bi-tablet::before { content: "\f5ae"; } +.bi-tag-fill::before { content: "\f5af"; } +.bi-tag::before { content: "\f5b0"; } +.bi-tags-fill::before { content: "\f5b1"; } +.bi-tags::before { content: "\f5b2"; } +.bi-telegram::before { content: "\f5b3"; } +.bi-telephone-fill::before { content: "\f5b4"; } +.bi-telephone-forward-fill::before { content: "\f5b5"; } +.bi-telephone-forward::before { content: "\f5b6"; } +.bi-telephone-inbound-fill::before { content: "\f5b7"; } +.bi-telephone-inbound::before { content: "\f5b8"; } +.bi-telephone-minus-fill::before { content: "\f5b9"; } +.bi-telephone-minus::before { content: "\f5ba"; } +.bi-telephone-outbound-fill::before { content: "\f5bb"; } +.bi-telephone-outbound::before { content: "\f5bc"; } +.bi-telephone-plus-fill::before { content: "\f5bd"; } +.bi-telephone-plus::before { content: "\f5be"; } +.bi-telephone-x-fill::before { content: "\f5bf"; } +.bi-telephone-x::before { content: "\f5c0"; } +.bi-telephone::before { content: "\f5c1"; } +.bi-terminal-fill::before { content: "\f5c2"; } +.bi-terminal::before { content: "\f5c3"; } +.bi-text-center::before { content: "\f5c4"; } +.bi-text-indent-left::before { content: "\f5c5"; } +.bi-text-indent-right::before { content: "\f5c6"; } +.bi-text-left::before { content: "\f5c7"; } +.bi-text-paragraph::before { content: "\f5c8"; } +.bi-text-right::before { content: "\f5c9"; } +.bi-textarea-resize::before { content: "\f5ca"; } +.bi-textarea-t::before { content: "\f5cb"; } +.bi-textarea::before { content: "\f5cc"; } +.bi-thermometer-half::before { content: "\f5cd"; } +.bi-thermometer-high::before { content: "\f5ce"; } +.bi-thermometer-low::before { content: "\f5cf"; } +.bi-thermometer-snow::before { content: "\f5d0"; } +.bi-thermometer-sun::before { content: "\f5d1"; } +.bi-thermometer::before { content: "\f5d2"; } +.bi-three-dots-vertical::before { content: "\f5d3"; } +.bi-three-dots::before { content: "\f5d4"; } +.bi-toggle-off::before { content: "\f5d5"; } +.bi-toggle-on::before { content: "\f5d6"; } +.bi-toggle2-off::before { content: "\f5d7"; } +.bi-toggle2-on::before { content: "\f5d8"; } +.bi-toggles::before { content: "\f5d9"; } +.bi-toggles2::before { content: "\f5da"; } +.bi-tools::before { content: "\f5db"; } +.bi-tornado::before { content: "\f5dc"; } +.bi-trash-fill::before { content: "\f5dd"; } +.bi-trash::before { content: "\f5de"; } +.bi-trash2-fill::before { content: "\f5df"; } +.bi-trash2::before { content: "\f5e0"; } +.bi-tree-fill::before { content: "\f5e1"; } +.bi-tree::before { content: "\f5e2"; } +.bi-triangle-fill::before { content: "\f5e3"; } +.bi-triangle-half::before { content: "\f5e4"; } +.bi-triangle::before { content: "\f5e5"; } +.bi-trophy-fill::before { content: "\f5e6"; } +.bi-trophy::before { content: "\f5e7"; } +.bi-tropical-storm::before { content: "\f5e8"; } +.bi-truck-flatbed::before { content: "\f5e9"; } +.bi-truck::before { content: "\f5ea"; } +.bi-tsunami::before { content: "\f5eb"; } +.bi-tv-fill::before { content: "\f5ec"; } +.bi-tv::before { content: "\f5ed"; } +.bi-twitch::before { content: "\f5ee"; } +.bi-twitter::before { content: "\f5ef"; } +.bi-type-bold::before { content: "\f5f0"; } +.bi-type-h1::before { content: "\f5f1"; } +.bi-type-h2::before { content: "\f5f2"; } +.bi-type-h3::before { content: "\f5f3"; } +.bi-type-italic::before { content: "\f5f4"; } +.bi-type-strikethrough::before { content: "\f5f5"; } +.bi-type-underline::before { content: "\f5f6"; } +.bi-type::before { content: "\f5f7"; } +.bi-ui-checks-grid::before { content: "\f5f8"; } +.bi-ui-checks::before { content: "\f5f9"; } +.bi-ui-radios-grid::before { content: "\f5fa"; } +.bi-ui-radios::before { content: "\f5fb"; } +.bi-umbrella-fill::before { content: "\f5fc"; } +.bi-umbrella::before { content: "\f5fd"; } +.bi-union::before { content: "\f5fe"; } +.bi-unlock-fill::before { content: "\f5ff"; } +.bi-unlock::before { content: "\f600"; } +.bi-upc-scan::before { content: "\f601"; } +.bi-upc::before { content: "\f602"; } +.bi-upload::before { content: "\f603"; } +.bi-vector-pen::before { content: "\f604"; } +.bi-view-list::before { content: "\f605"; } +.bi-view-stacked::before { content: "\f606"; } +.bi-vinyl-fill::before { content: "\f607"; } +.bi-vinyl::before { content: "\f608"; } +.bi-voicemail::before { content: "\f609"; } +.bi-volume-down-fill::before { content: "\f60a"; } +.bi-volume-down::before { content: "\f60b"; } +.bi-volume-mute-fill::before { content: "\f60c"; } +.bi-volume-mute::before { content: "\f60d"; } +.bi-volume-off-fill::before { content: "\f60e"; } +.bi-volume-off::before { content: "\f60f"; } +.bi-volume-up-fill::before { content: "\f610"; } +.bi-volume-up::before { content: "\f611"; } +.bi-vr::before { content: "\f612"; } +.bi-wallet-fill::before { content: "\f613"; } +.bi-wallet::before { content: "\f614"; } +.bi-wallet2::before { content: "\f615"; } +.bi-watch::before { content: "\f616"; } +.bi-water::before { content: "\f617"; } +.bi-whatsapp::before { content: "\f618"; } +.bi-wifi-1::before { content: "\f619"; } +.bi-wifi-2::before { content: "\f61a"; } +.bi-wifi-off::before { content: "\f61b"; } +.bi-wifi::before { content: "\f61c"; } +.bi-wind::before { content: "\f61d"; } +.bi-window-dock::before { content: "\f61e"; } +.bi-window-sidebar::before { content: "\f61f"; } +.bi-window::before { content: "\f620"; } +.bi-wrench::before { content: "\f621"; } +.bi-x-circle-fill::before { content: "\f622"; } +.bi-x-circle::before { content: "\f623"; } +.bi-x-diamond-fill::before { content: "\f624"; } +.bi-x-diamond::before { content: "\f625"; } +.bi-x-octagon-fill::before { content: "\f626"; } +.bi-x-octagon::before { content: "\f627"; } +.bi-x-square-fill::before { content: "\f628"; } +.bi-x-square::before { content: "\f629"; } +.bi-x::before { content: "\f62a"; } +.bi-youtube::before { content: "\f62b"; } +.bi-zoom-in::before { content: "\f62c"; } +.bi-zoom-out::before { content: "\f62d"; } +.bi-bank::before { content: "\f62e"; } +.bi-bank2::before { content: "\f62f"; } +.bi-bell-slash-fill::before { content: "\f630"; } +.bi-bell-slash::before { content: "\f631"; } +.bi-cash-coin::before { content: "\f632"; } +.bi-check-lg::before { content: "\f633"; } +.bi-coin::before { content: "\f634"; } +.bi-currency-bitcoin::before { content: "\f635"; } +.bi-currency-dollar::before { content: "\f636"; } +.bi-currency-euro::before { content: "\f637"; } +.bi-currency-exchange::before { content: "\f638"; } +.bi-currency-pound::before { content: "\f639"; } +.bi-currency-yen::before { content: "\f63a"; } +.bi-dash-lg::before { content: "\f63b"; } +.bi-exclamation-lg::before { content: "\f63c"; } +.bi-file-earmark-pdf-fill::before { content: "\f63d"; } +.bi-file-earmark-pdf::before { content: "\f63e"; } +.bi-file-pdf-fill::before { content: "\f63f"; } +.bi-file-pdf::before { content: "\f640"; } +.bi-gender-ambiguous::before { content: "\f641"; } +.bi-gender-female::before { content: "\f642"; } +.bi-gender-male::before { content: "\f643"; } +.bi-gender-trans::before { content: "\f644"; } +.bi-headset-vr::before { content: "\f645"; } +.bi-info-lg::before { content: "\f646"; } +.bi-mastodon::before { content: "\f647"; } +.bi-messenger::before { content: "\f648"; } +.bi-piggy-bank-fill::before { content: "\f649"; } +.bi-piggy-bank::before { content: "\f64a"; } +.bi-pin-map-fill::before { content: "\f64b"; } +.bi-pin-map::before { content: "\f64c"; } +.bi-plus-lg::before { content: "\f64d"; } +.bi-question-lg::before { content: "\f64e"; } +.bi-recycle::before { content: "\f64f"; } +.bi-reddit::before { content: "\f650"; } +.bi-safe-fill::before { content: "\f651"; } +.bi-safe2-fill::before { content: "\f652"; } +.bi-safe2::before { content: "\f653"; } +.bi-sd-card-fill::before { content: "\f654"; } +.bi-sd-card::before { content: "\f655"; } +.bi-skype::before { content: "\f656"; } +.bi-slash-lg::before { content: "\f657"; } +.bi-translate::before { content: "\f658"; } +.bi-x-lg::before { content: "\f659"; } +.bi-safe::before { content: "\f65a"; } +.bi-apple::before { content: "\f65b"; } +.bi-microsoft::before { content: "\f65d"; } +.bi-windows::before { content: "\f65e"; } +.bi-behance::before { content: "\f65c"; } +.bi-dribbble::before { content: "\f65f"; } +.bi-line::before { content: "\f660"; } +.bi-medium::before { content: "\f661"; } +.bi-paypal::before { content: "\f662"; } +.bi-pinterest::before { content: "\f663"; } +.bi-signal::before { content: "\f664"; } +.bi-snapchat::before { content: "\f665"; } +.bi-spotify::before { content: "\f666"; } +.bi-stack-overflow::before { content: "\f667"; } +.bi-strava::before { content: "\f668"; } +.bi-wordpress::before { content: "\f669"; } +.bi-vimeo::before { content: "\f66a"; } +.bi-activity::before { content: "\f66b"; } +.bi-easel2-fill::before { content: "\f66c"; } +.bi-easel2::before { content: "\f66d"; } +.bi-easel3-fill::before { content: "\f66e"; } +.bi-easel3::before { content: "\f66f"; } +.bi-fan::before { content: "\f670"; } +.bi-fingerprint::before { content: "\f671"; } +.bi-graph-down-arrow::before { content: "\f672"; } +.bi-graph-up-arrow::before { content: "\f673"; } +.bi-hypnotize::before { content: "\f674"; } +.bi-magic::before { content: "\f675"; } +.bi-person-rolodex::before { content: "\f676"; } +.bi-person-video::before { content: "\f677"; } +.bi-person-video2::before { content: "\f678"; } +.bi-person-video3::before { content: "\f679"; } +.bi-person-workspace::before { content: "\f67a"; } +.bi-radioactive::before { content: "\f67b"; } +.bi-webcam-fill::before { content: "\f67c"; } +.bi-webcam::before { content: "\f67d"; } +.bi-yin-yang::before { content: "\f67e"; } +.bi-bandaid-fill::before { content: "\f680"; } +.bi-bandaid::before { content: "\f681"; } +.bi-bluetooth::before { content: "\f682"; } +.bi-body-text::before { content: "\f683"; } +.bi-boombox::before { content: "\f684"; } +.bi-boxes::before { content: "\f685"; } +.bi-dpad-fill::before { content: "\f686"; } +.bi-dpad::before { content: "\f687"; } +.bi-ear-fill::before { content: "\f688"; } +.bi-ear::before { content: "\f689"; } +.bi-envelope-check-1::before { content: "\f68a"; } +.bi-envelope-check-fill::before { content: "\f68b"; } +.bi-envelope-check::before { content: "\f68c"; } +.bi-envelope-dash-1::before { content: "\f68d"; } +.bi-envelope-dash-fill::before { content: "\f68e"; } +.bi-envelope-dash::before { content: "\f68f"; } +.bi-envelope-exclamation-1::before { content: "\f690"; } +.bi-envelope-exclamation-fill::before { content: "\f691"; } +.bi-envelope-exclamation::before { content: "\f692"; } +.bi-envelope-plus-fill::before { content: "\f693"; } +.bi-envelope-plus::before { content: "\f694"; } +.bi-envelope-slash-1::before { content: "\f695"; } +.bi-envelope-slash-fill::before { content: "\f696"; } +.bi-envelope-slash::before { content: "\f697"; } +.bi-envelope-x-1::before { content: "\f698"; } +.bi-envelope-x-fill::before { content: "\f699"; } +.bi-envelope-x::before { content: "\f69a"; } +.bi-explicit-fill::before { content: "\f69b"; } +.bi-explicit::before { content: "\f69c"; } +.bi-git::before { content: "\f69d"; } +.bi-infinity::before { content: "\f69e"; } +.bi-list-columns-reverse::before { content: "\f69f"; } +.bi-list-columns::before { content: "\f6a0"; } +.bi-meta::before { content: "\f6a1"; } +.bi-mortorboard-fill::before { content: "\f6a2"; } +.bi-mortorboard::before { content: "\f6a3"; } +.bi-nintendo-switch::before { content: "\f6a4"; } +.bi-pc-display-horizontal::before { content: "\f6a5"; } +.bi-pc-display::before { content: "\f6a6"; } +.bi-pc-horizontal::before { content: "\f6a7"; } +.bi-pc::before { content: "\f6a8"; } +.bi-playstation::before { content: "\f6a9"; } +.bi-plus-slash-minus::before { content: "\f6aa"; } +.bi-projector-fill::before { content: "\f6ab"; } +.bi-projector::before { content: "\f6ac"; } +.bi-qr-code-scan::before { content: "\f6ad"; } +.bi-qr-code::before { content: "\f6ae"; } +.bi-quora::before { content: "\f6af"; } +.bi-quote::before { content: "\f6b0"; } +.bi-robot::before { content: "\f6b1"; } +.bi-send-check-fill::before { content: "\f6b2"; } +.bi-send-check::before { content: "\f6b3"; } +.bi-send-dash-fill::before { content: "\f6b4"; } +.bi-send-dash::before { content: "\f6b5"; } +.bi-send-exclamation-1::before { content: "\f6b6"; } +.bi-send-exclamation-fill::before { content: "\f6b7"; } +.bi-send-exclamation::before { content: "\f6b8"; } +.bi-send-fill::before { content: "\f6b9"; } +.bi-send-plus-fill::before { content: "\f6ba"; } +.bi-send-plus::before { content: "\f6bb"; } +.bi-send-slash-fill::before { content: "\f6bc"; } +.bi-send-slash::before { content: "\f6bd"; } +.bi-send-x-fill::before { content: "\f6be"; } +.bi-send-x::before { content: "\f6bf"; } +.bi-send::before { content: "\f6c0"; } +.bi-steam::before { content: "\f6c1"; } +.bi-terminal-dash-1::before { content: "\f6c2"; } +.bi-terminal-dash::before { content: "\f6c3"; } +.bi-terminal-plus::before { content: "\f6c4"; } +.bi-terminal-split::before { content: "\f6c5"; } +.bi-ticket-detailed-fill::before { content: "\f6c6"; } +.bi-ticket-detailed::before { content: "\f6c7"; } +.bi-ticket-fill::before { content: "\f6c8"; } +.bi-ticket-perforated-fill::before { content: "\f6c9"; } +.bi-ticket-perforated::before { content: "\f6ca"; } +.bi-ticket::before { content: "\f6cb"; } +.bi-tiktok::before { content: "\f6cc"; } +.bi-window-dash::before { content: "\f6cd"; } +.bi-window-desktop::before { content: "\f6ce"; } +.bi-window-fullscreen::before { content: "\f6cf"; } +.bi-window-plus::before { content: "\f6d0"; } +.bi-window-split::before { content: "\f6d1"; } +.bi-window-stack::before { content: "\f6d2"; } +.bi-window-x::before { content: "\f6d3"; } +.bi-xbox::before { content: "\f6d4"; } +.bi-ethernet::before { content: "\f6d5"; } +.bi-hdmi-fill::before { content: "\f6d6"; } +.bi-hdmi::before { content: "\f6d7"; } +.bi-usb-c-fill::before { content: "\f6d8"; } +.bi-usb-c::before { content: "\f6d9"; } +.bi-usb-fill::before { content: "\f6da"; } +.bi-usb-plug-fill::before { content: "\f6db"; } +.bi-usb-plug::before { content: "\f6dc"; } +.bi-usb-symbol::before { content: "\f6dd"; } +.bi-usb::before { content: "\f6de"; } +.bi-boombox-fill::before { content: "\f6df"; } +.bi-displayport-1::before { content: "\f6e0"; } +.bi-displayport::before { content: "\f6e1"; } +.bi-gpu-card::before { content: "\f6e2"; } +.bi-memory::before { content: "\f6e3"; } +.bi-modem-fill::before { content: "\f6e4"; } +.bi-modem::before { content: "\f6e5"; } +.bi-motherboard-fill::before { content: "\f6e6"; } +.bi-motherboard::before { content: "\f6e7"; } +.bi-optical-audio-fill::before { content: "\f6e8"; } +.bi-optical-audio::before { content: "\f6e9"; } +.bi-pci-card::before { content: "\f6ea"; } +.bi-router-fill::before { content: "\f6eb"; } +.bi-router::before { content: "\f6ec"; } +.bi-ssd-fill::before { content: "\f6ed"; } +.bi-ssd::before { content: "\f6ee"; } +.bi-thunderbolt-fill::before { content: "\f6ef"; } +.bi-thunderbolt::before { content: "\f6f0"; } +.bi-usb-drive-fill::before { content: "\f6f1"; } +.bi-usb-drive::before { content: "\f6f2"; } +.bi-usb-micro-fill::before { content: "\f6f3"; } +.bi-usb-micro::before { content: "\f6f4"; } +.bi-usb-mini-fill::before { content: "\f6f5"; } +.bi-usb-mini::before { content: "\f6f6"; } +.bi-cloud-haze2::before { content: "\f6f7"; } +.bi-device-hdd-fill::before { content: "\f6f8"; } +.bi-device-hdd::before { content: "\f6f9"; } +.bi-device-ssd-fill::before { content: "\f6fa"; } +.bi-device-ssd::before { content: "\f6fb"; } +.bi-displayport-fill::before { content: "\f6fc"; } +.bi-mortarboard-fill::before { content: "\f6fd"; } +.bi-mortarboard::before { content: "\f6fe"; } +.bi-terminal-x::before { content: "\f6ff"; } +.bi-arrow-through-heart-fill::before { content: "\f700"; } +.bi-arrow-through-heart::before { content: "\f701"; } +.bi-badge-sd-fill::before { content: "\f702"; } +.bi-badge-sd::before { content: "\f703"; } +.bi-bag-heart-fill::before { content: "\f704"; } +.bi-bag-heart::before { content: "\f705"; } +.bi-balloon-fill::before { content: "\f706"; } +.bi-balloon-heart-fill::before { content: "\f707"; } +.bi-balloon-heart::before { content: "\f708"; } +.bi-balloon::before { content: "\f709"; } +.bi-box2-fill::before { content: "\f70a"; } +.bi-box2-heart-fill::before { content: "\f70b"; } +.bi-box2-heart::before { content: "\f70c"; } +.bi-box2::before { content: "\f70d"; } +.bi-braces-asterisk::before { content: "\f70e"; } +.bi-calendar-heart-fill::before { content: "\f70f"; } +.bi-calendar-heart::before { content: "\f710"; } +.bi-calendar2-heart-fill::before { content: "\f711"; } +.bi-calendar2-heart::before { content: "\f712"; } +.bi-chat-heart-fill::before { content: "\f713"; } +.bi-chat-heart::before { content: "\f714"; } +.bi-chat-left-heart-fill::before { content: "\f715"; } +.bi-chat-left-heart::before { content: "\f716"; } +.bi-chat-right-heart-fill::before { content: "\f717"; } +.bi-chat-right-heart::before { content: "\f718"; } +.bi-chat-square-heart-fill::before { content: "\f719"; } +.bi-chat-square-heart::before { content: "\f71a"; } +.bi-clipboard-check-fill::before { content: "\f71b"; } +.bi-clipboard-data-fill::before { content: "\f71c"; } +.bi-clipboard-fill::before { content: "\f71d"; } +.bi-clipboard-heart-fill::before { content: "\f71e"; } +.bi-clipboard-heart::before { content: "\f71f"; } +.bi-clipboard-minus-fill::before { content: "\f720"; } +.bi-clipboard-plus-fill::before { content: "\f721"; } +.bi-clipboard-pulse::before { content: "\f722"; } +.bi-clipboard-x-fill::before { content: "\f723"; } +.bi-clipboard2-check-fill::before { content: "\f724"; } +.bi-clipboard2-check::before { content: "\f725"; } +.bi-clipboard2-data-fill::before { content: "\f726"; } +.bi-clipboard2-data::before { content: "\f727"; } +.bi-clipboard2-fill::before { content: "\f728"; } +.bi-clipboard2-heart-fill::before { content: "\f729"; } +.bi-clipboard2-heart::before { content: "\f72a"; } +.bi-clipboard2-minus-fill::before { content: "\f72b"; } +.bi-clipboard2-minus::before { content: "\f72c"; } +.bi-clipboard2-plus-fill::before { content: "\f72d"; } +.bi-clipboard2-plus::before { content: "\f72e"; } +.bi-clipboard2-pulse-fill::before { content: "\f72f"; } +.bi-clipboard2-pulse::before { content: "\f730"; } +.bi-clipboard2-x-fill::before { content: "\f731"; } +.bi-clipboard2-x::before { content: "\f732"; } +.bi-clipboard2::before { content: "\f733"; } +.bi-emoji-kiss-fill::before { content: "\f734"; } +.bi-emoji-kiss::before { content: "\f735"; } +.bi-envelope-heart-fill::before { content: "\f736"; } +.bi-envelope-heart::before { content: "\f737"; } +.bi-envelope-open-heart-fill::before { content: "\f738"; } +.bi-envelope-open-heart::before { content: "\f739"; } +.bi-envelope-paper-fill::before { content: "\f73a"; } +.bi-envelope-paper-heart-fill::before { content: "\f73b"; } +.bi-envelope-paper-heart::before { content: "\f73c"; } +.bi-envelope-paper::before { content: "\f73d"; } +.bi-filetype-aac::before { content: "\f73e"; } +.bi-filetype-ai::before { content: "\f73f"; } +.bi-filetype-bmp::before { content: "\f740"; } +.bi-filetype-cs::before { content: "\f741"; } +.bi-filetype-css::before { content: "\f742"; } +.bi-filetype-csv::before { content: "\f743"; } +.bi-filetype-doc::before { content: "\f744"; } +.bi-filetype-docx::before { content: "\f745"; } +.bi-filetype-exe::before { content: "\f746"; } +.bi-filetype-gif::before { content: "\f747"; } +.bi-filetype-heic::before { content: "\f748"; } +.bi-filetype-html::before { content: "\f749"; } +.bi-filetype-java::before { content: "\f74a"; } +.bi-filetype-jpg::before { content: "\f74b"; } +.bi-filetype-js::before { content: "\f74c"; } +.bi-filetype-jsx::before { content: "\f74d"; } +.bi-filetype-key::before { content: "\f74e"; } +.bi-filetype-m4p::before { content: "\f74f"; } +.bi-filetype-md::before { content: "\f750"; } +.bi-filetype-mdx::before { content: "\f751"; } +.bi-filetype-mov::before { content: "\f752"; } +.bi-filetype-mp3::before { content: "\f753"; } +.bi-filetype-mp4::before { content: "\f754"; } +.bi-filetype-otf::before { content: "\f755"; } +.bi-filetype-pdf::before { content: "\f756"; } +.bi-filetype-php::before { content: "\f757"; } +.bi-filetype-png::before { content: "\f758"; } +.bi-filetype-ppt-1::before { content: "\f759"; } +.bi-filetype-ppt::before { content: "\f75a"; } +.bi-filetype-psd::before { content: "\f75b"; } +.bi-filetype-py::before { content: "\f75c"; } +.bi-filetype-raw::before { content: "\f75d"; } +.bi-filetype-rb::before { content: "\f75e"; } +.bi-filetype-sass::before { content: "\f75f"; } +.bi-filetype-scss::before { content: "\f760"; } +.bi-filetype-sh::before { content: "\f761"; } +.bi-filetype-svg::before { content: "\f762"; } +.bi-filetype-tiff::before { content: "\f763"; } +.bi-filetype-tsx::before { content: "\f764"; } +.bi-filetype-ttf::before { content: "\f765"; } +.bi-filetype-txt::before { content: "\f766"; } +.bi-filetype-wav::before { content: "\f767"; } +.bi-filetype-woff::before { content: "\f768"; } +.bi-filetype-xls-1::before { content: "\f769"; } +.bi-filetype-xls::before { content: "\f76a"; } +.bi-filetype-xml::before { content: "\f76b"; } +.bi-filetype-yml::before { content: "\f76c"; } +.bi-heart-arrow::before { content: "\f76d"; } +.bi-heart-pulse-fill::before { content: "\f76e"; } +.bi-heart-pulse::before { content: "\f76f"; } +.bi-heartbreak-fill::before { content: "\f770"; } +.bi-heartbreak::before { content: "\f771"; } +.bi-hearts::before { content: "\f772"; } +.bi-hospital-fill::before { content: "\f773"; } +.bi-hospital::before { content: "\f774"; } +.bi-house-heart-fill::before { content: "\f775"; } +.bi-house-heart::before { content: "\f776"; } +.bi-incognito::before { content: "\f777"; } +.bi-magnet-fill::before { content: "\f778"; } +.bi-magnet::before { content: "\f779"; } +.bi-person-heart::before { content: "\f77a"; } +.bi-person-hearts::before { content: "\f77b"; } +.bi-phone-flip::before { content: "\f77c"; } +.bi-plugin::before { content: "\f77d"; } +.bi-postage-fill::before { content: "\f77e"; } +.bi-postage-heart-fill::before { content: "\f77f"; } +.bi-postage-heart::before { content: "\f780"; } +.bi-postage::before { content: "\f781"; } +.bi-postcard-fill::before { content: "\f782"; } +.bi-postcard-heart-fill::before { content: "\f783"; } +.bi-postcard-heart::before { content: "\f784"; } +.bi-postcard::before { content: "\f785"; } +.bi-search-heart-fill::before { content: "\f786"; } +.bi-search-heart::before { content: "\f787"; } +.bi-sliders2-vertical::before { content: "\f788"; } +.bi-sliders2::before { content: "\f789"; } +.bi-trash3-fill::before { content: "\f78a"; } +.bi-trash3::before { content: "\f78b"; } +.bi-valentine::before { content: "\f78c"; } +.bi-valentine2::before { content: "\f78d"; } +.bi-wrench-adjustable-circle-fill::before { content: "\f78e"; } +.bi-wrench-adjustable-circle::before { content: "\f78f"; } +.bi-wrench-adjustable::before { content: "\f790"; } +.bi-filetype-json::before { content: "\f791"; } +.bi-filetype-pptx::before { content: "\f792"; } +.bi-filetype-xlsx::before { content: "\f793"; } +.bi-1-circle-1::before { content: "\f794"; } +.bi-1-circle-fill-1::before { content: "\f795"; } +.bi-1-circle-fill::before { content: "\f796"; } +.bi-1-circle::before { content: "\f797"; } +.bi-1-square-fill::before { content: "\f798"; } +.bi-1-square::before { content: "\f799"; } +.bi-2-circle-1::before { content: "\f79a"; } +.bi-2-circle-fill-1::before { content: "\f79b"; } +.bi-2-circle-fill::before { content: "\f79c"; } +.bi-2-circle::before { content: "\f79d"; } +.bi-2-square-fill::before { content: "\f79e"; } +.bi-2-square::before { content: "\f79f"; } +.bi-3-circle-1::before { content: "\f7a0"; } +.bi-3-circle-fill-1::before { content: "\f7a1"; } +.bi-3-circle-fill::before { content: "\f7a2"; } +.bi-3-circle::before { content: "\f7a3"; } +.bi-3-square-fill::before { content: "\f7a4"; } +.bi-3-square::before { content: "\f7a5"; } +.bi-4-circle-1::before { content: "\f7a6"; } +.bi-4-circle-fill-1::before { content: "\f7a7"; } +.bi-4-circle-fill::before { content: "\f7a8"; } +.bi-4-circle::before { content: "\f7a9"; } +.bi-4-square-fill::before { content: "\f7aa"; } +.bi-4-square::before { content: "\f7ab"; } +.bi-5-circle-1::before { content: "\f7ac"; } +.bi-5-circle-fill-1::before { content: "\f7ad"; } +.bi-5-circle-fill::before { content: "\f7ae"; } +.bi-5-circle::before { content: "\f7af"; } +.bi-5-square-fill::before { content: "\f7b0"; } +.bi-5-square::before { content: "\f7b1"; } +.bi-6-circle-1::before { content: "\f7b2"; } +.bi-6-circle-fill-1::before { content: "\f7b3"; } +.bi-6-circle-fill::before { content: "\f7b4"; } +.bi-6-circle::before { content: "\f7b5"; } +.bi-6-square-fill::before { content: "\f7b6"; } +.bi-6-square::before { content: "\f7b7"; } +.bi-7-circle-1::before { content: "\f7b8"; } +.bi-7-circle-fill-1::before { content: "\f7b9"; } +.bi-7-circle-fill::before { content: "\f7ba"; } +.bi-7-circle::before { content: "\f7bb"; } +.bi-7-square-fill::before { content: "\f7bc"; } +.bi-7-square::before { content: "\f7bd"; } +.bi-8-circle-1::before { content: "\f7be"; } +.bi-8-circle-fill-1::before { content: "\f7bf"; } +.bi-8-circle-fill::before { content: "\f7c0"; } +.bi-8-circle::before { content: "\f7c1"; } +.bi-8-square-fill::before { content: "\f7c2"; } +.bi-8-square::before { content: "\f7c3"; } +.bi-9-circle-1::before { content: "\f7c4"; } +.bi-9-circle-fill-1::before { content: "\f7c5"; } +.bi-9-circle-fill::before { content: "\f7c6"; } +.bi-9-circle::before { content: "\f7c7"; } +.bi-9-square-fill::before { content: "\f7c8"; } +.bi-9-square::before { content: "\f7c9"; } +.bi-airplane-engines-fill::before { content: "\f7ca"; } +.bi-airplane-engines::before { content: "\f7cb"; } +.bi-airplane-fill::before { content: "\f7cc"; } +.bi-airplane::before { content: "\f7cd"; } +.bi-alexa::before { content: "\f7ce"; } +.bi-alipay::before { content: "\f7cf"; } +.bi-android::before { content: "\f7d0"; } +.bi-android2::before { content: "\f7d1"; } +.bi-box-fill::before { content: "\f7d2"; } +.bi-box-seam-fill::before { content: "\f7d3"; } +.bi-browser-chrome::before { content: "\f7d4"; } +.bi-browser-edge::before { content: "\f7d5"; } +.bi-browser-firefox::before { content: "\f7d6"; } +.bi-browser-safari::before { content: "\f7d7"; } +.bi-c-circle-1::before { content: "\f7d8"; } +.bi-c-circle-fill-1::before { content: "\f7d9"; } +.bi-c-circle-fill::before { content: "\f7da"; } +.bi-c-circle::before { content: "\f7db"; } +.bi-c-square-fill::before { content: "\f7dc"; } +.bi-c-square::before { content: "\f7dd"; } +.bi-capsule-pill::before { content: "\f7de"; } +.bi-capsule::before { content: "\f7df"; } +.bi-car-front-fill::before { content: "\f7e0"; } +.bi-car-front::before { content: "\f7e1"; } +.bi-cassette-fill::before { content: "\f7e2"; } +.bi-cassette::before { content: "\f7e3"; } +.bi-cc-circle-1::before { content: "\f7e4"; } +.bi-cc-circle-fill-1::before { content: "\f7e5"; } +.bi-cc-circle-fill::before { content: "\f7e6"; } +.bi-cc-circle::before { content: "\f7e7"; } +.bi-cc-square-fill::before { content: "\f7e8"; } +.bi-cc-square::before { content: "\f7e9"; } +.bi-cup-hot-fill::before { content: "\f7ea"; } +.bi-cup-hot::before { content: "\f7eb"; } +.bi-currency-rupee::before { content: "\f7ec"; } +.bi-dropbox::before { content: "\f7ed"; } +.bi-escape::before { content: "\f7ee"; } +.bi-fast-forward-btn-fill::before { content: "\f7ef"; } +.bi-fast-forward-btn::before { content: "\f7f0"; } +.bi-fast-forward-circle-fill::before { content: "\f7f1"; } +.bi-fast-forward-circle::before { content: "\f7f2"; } +.bi-fast-forward-fill::before { content: "\f7f3"; } +.bi-fast-forward::before { content: "\f7f4"; } +.bi-filetype-sql::before { content: "\f7f5"; } +.bi-fire::before { content: "\f7f6"; } +.bi-google-play::before { content: "\f7f7"; } +.bi-h-circle-1::before { content: "\f7f8"; } +.bi-h-circle-fill-1::before { content: "\f7f9"; } +.bi-h-circle-fill::before { content: "\f7fa"; } +.bi-h-circle::before { content: "\f7fb"; } +.bi-h-square-fill::before { content: "\f7fc"; } +.bi-h-square::before { content: "\f7fd"; } +.bi-indent::before { content: "\f7fe"; } +.bi-lungs-fill::before { content: "\f7ff"; } +.bi-lungs::before { content: "\f800"; } +.bi-microsoft-teams::before { content: "\f801"; } +.bi-p-circle-1::before { content: "\f802"; } +.bi-p-circle-fill-1::before { content: "\f803"; } +.bi-p-circle-fill::before { content: "\f804"; } +.bi-p-circle::before { content: "\f805"; } +.bi-p-square-fill::before { content: "\f806"; } +.bi-p-square::before { content: "\f807"; } +.bi-pass-fill::before { content: "\f808"; } +.bi-pass::before { content: "\f809"; } +.bi-prescription::before { content: "\f80a"; } +.bi-prescription2::before { content: "\f80b"; } +.bi-r-circle-1::before { content: "\f80c"; } +.bi-r-circle-fill-1::before { content: "\f80d"; } +.bi-r-circle-fill::before { content: "\f80e"; } +.bi-r-circle::before { content: "\f80f"; } +.bi-r-square-fill::before { content: "\f810"; } +.bi-r-square::before { content: "\f811"; } +.bi-repeat-1::before { content: "\f812"; } +.bi-repeat::before { content: "\f813"; } +.bi-rewind-btn-fill::before { content: "\f814"; } +.bi-rewind-btn::before { content: "\f815"; } +.bi-rewind-circle-fill::before { content: "\f816"; } +.bi-rewind-circle::before { content: "\f817"; } +.bi-rewind-fill::before { content: "\f818"; } +.bi-rewind::before { content: "\f819"; } +.bi-train-freight-front-fill::before { content: "\f81a"; } +.bi-train-freight-front::before { content: "\f81b"; } +.bi-train-front-fill::before { content: "\f81c"; } +.bi-train-front::before { content: "\f81d"; } +.bi-train-lightrail-front-fill::before { content: "\f81e"; } +.bi-train-lightrail-front::before { content: "\f81f"; } +.bi-truck-front-fill::before { content: "\f820"; } +.bi-truck-front::before { content: "\f821"; } +.bi-ubuntu::before { content: "\f822"; } +.bi-unindent::before { content: "\f823"; } +.bi-unity::before { content: "\f824"; } +.bi-universal-access-circle::before { content: "\f825"; } +.bi-universal-access::before { content: "\f826"; } +.bi-virus::before { content: "\f827"; } +.bi-virus2::before { content: "\f828"; } +.bi-wechat::before { content: "\f829"; } +.bi-yelp::before { content: "\f82a"; } +.bi-sign-stop-fill::before { content: "\f82b"; } +.bi-sign-stop-lights-fill::before { content: "\f82c"; } +.bi-sign-stop-lights::before { content: "\f82d"; } +.bi-sign-stop::before { content: "\f82e"; } +.bi-sign-turn-left-fill::before { content: "\f82f"; } +.bi-sign-turn-left::before { content: "\f830"; } +.bi-sign-turn-right-fill::before { content: "\f831"; } +.bi-sign-turn-right::before { content: "\f832"; } +.bi-sign-turn-slight-left-fill::before { content: "\f833"; } +.bi-sign-turn-slight-left::before { content: "\f834"; } +.bi-sign-turn-slight-right-fill::before { content: "\f835"; } +.bi-sign-turn-slight-right::before { content: "\f836"; } +.bi-sign-yield-fill::before { content: "\f837"; } +.bi-sign-yield::before { content: "\f838"; } +.bi-ev-station-fill::before { content: "\f839"; } +.bi-ev-station::before { content: "\f83a"; } +.bi-fuel-pump-diesel-fill::before { content: "\f83b"; } +.bi-fuel-pump-diesel::before { content: "\f83c"; } +.bi-fuel-pump-fill::before { content: "\f83d"; } +.bi-fuel-pump::before { content: "\f83e"; } +.bi-0-circle-fill::before { content: "\f83f"; } +.bi-0-circle::before { content: "\f840"; } +.bi-0-square-fill::before { content: "\f841"; } +.bi-0-square::before { content: "\f842"; } +.bi-rocket-fill::before { content: "\f843"; } +.bi-rocket-takeoff-fill::before { content: "\f844"; } +.bi-rocket-takeoff::before { content: "\f845"; } +.bi-rocket::before { content: "\f846"; } +.bi-stripe::before { content: "\f847"; } +.bi-subscript::before { content: "\f848"; } +.bi-superscript::before { content: "\f849"; } +.bi-trello::before { content: "\f84a"; } +.bi-envelope-at-fill::before { content: "\f84b"; } +.bi-envelope-at::before { content: "\f84c"; } +.bi-regex::before { content: "\f84d"; } +.bi-text-wrap::before { content: "\f84e"; } +.bi-sign-dead-end-fill::before { content: "\f84f"; } +.bi-sign-dead-end::before { content: "\f850"; } +.bi-sign-do-not-enter-fill::before { content: "\f851"; } +.bi-sign-do-not-enter::before { content: "\f852"; } +.bi-sign-intersection-fill::before { content: "\f853"; } +.bi-sign-intersection-side-fill::before { content: "\f854"; } +.bi-sign-intersection-side::before { content: "\f855"; } +.bi-sign-intersection-t-fill::before { content: "\f856"; } +.bi-sign-intersection-t::before { content: "\f857"; } +.bi-sign-intersection-y-fill::before { content: "\f858"; } +.bi-sign-intersection-y::before { content: "\f859"; } +.bi-sign-intersection::before { content: "\f85a"; } +.bi-sign-merge-left-fill::before { content: "\f85b"; } +.bi-sign-merge-left::before { content: "\f85c"; } +.bi-sign-merge-right-fill::before { content: "\f85d"; } +.bi-sign-merge-right::before { content: "\f85e"; } +.bi-sign-no-left-turn-fill::before { content: "\f85f"; } +.bi-sign-no-left-turn::before { content: "\f860"; } +.bi-sign-no-parking-fill::before { content: "\f861"; } +.bi-sign-no-parking::before { content: "\f862"; } +.bi-sign-no-right-turn-fill::before { content: "\f863"; } +.bi-sign-no-right-turn::before { content: "\f864"; } +.bi-sign-railroad-fill::before { content: "\f865"; } +.bi-sign-railroad::before { content: "\f866"; } +.bi-building-add::before { content: "\f867"; } +.bi-building-check::before { content: "\f868"; } +.bi-building-dash::before { content: "\f869"; } +.bi-building-down::before { content: "\f86a"; } +.bi-building-exclamation::before { content: "\f86b"; } +.bi-building-fill-add::before { content: "\f86c"; } +.bi-building-fill-check::before { content: "\f86d"; } +.bi-building-fill-dash::before { content: "\f86e"; } +.bi-building-fill-down::before { content: "\f86f"; } +.bi-building-fill-exclamation::before { content: "\f870"; } +.bi-building-fill-gear::before { content: "\f871"; } +.bi-building-fill-lock::before { content: "\f872"; } +.bi-building-fill-slash::before { content: "\f873"; } +.bi-building-fill-up::before { content: "\f874"; } +.bi-building-fill-x::before { content: "\f875"; } +.bi-building-fill::before { content: "\f876"; } +.bi-building-gear::before { content: "\f877"; } +.bi-building-lock::before { content: "\f878"; } +.bi-building-slash::before { content: "\f879"; } +.bi-building-up::before { content: "\f87a"; } +.bi-building-x::before { content: "\f87b"; } +.bi-buildings-fill::before { content: "\f87c"; } +.bi-buildings::before { content: "\f87d"; } +.bi-bus-front-fill::before { content: "\f87e"; } +.bi-bus-front::before { content: "\f87f"; } +.bi-ev-front-fill::before { content: "\f880"; } +.bi-ev-front::before { content: "\f881"; } +.bi-globe-americas::before { content: "\f882"; } +.bi-globe-asia-australia::before { content: "\f883"; } +.bi-globe-central-south-asia::before { content: "\f884"; } +.bi-globe-europe-africa::before { content: "\f885"; } +.bi-house-add-fill::before { content: "\f886"; } +.bi-house-add::before { content: "\f887"; } +.bi-house-check-fill::before { content: "\f888"; } +.bi-house-check::before { content: "\f889"; } +.bi-house-dash-fill::before { content: "\f88a"; } +.bi-house-dash::before { content: "\f88b"; } +.bi-house-down-fill::before { content: "\f88c"; } +.bi-house-down::before { content: "\f88d"; } +.bi-house-exclamation-fill::before { content: "\f88e"; } +.bi-house-exclamation::before { content: "\f88f"; } +.bi-house-gear-fill::before { content: "\f890"; } +.bi-house-gear::before { content: "\f891"; } +.bi-house-lock-fill::before { content: "\f892"; } +.bi-house-lock::before { content: "\f893"; } +.bi-house-slash-fill::before { content: "\f894"; } +.bi-house-slash::before { content: "\f895"; } +.bi-house-up-fill::before { content: "\f896"; } +.bi-house-up::before { content: "\f897"; } +.bi-house-x-fill::before { content: "\f898"; } +.bi-house-x::before { content: "\f899"; } +.bi-person-add::before { content: "\f89a"; } +.bi-person-down::before { content: "\f89b"; } +.bi-person-exclamation::before { content: "\f89c"; } +.bi-person-fill-add::before { content: "\f89d"; } +.bi-person-fill-check::before { content: "\f89e"; } +.bi-person-fill-dash::before { content: "\f89f"; } +.bi-person-fill-down::before { content: "\f8a0"; } +.bi-person-fill-exclamation::before { content: "\f8a1"; } +.bi-person-fill-gear::before { content: "\f8a2"; } +.bi-person-fill-lock::before { content: "\f8a3"; } +.bi-person-fill-slash::before { content: "\f8a4"; } +.bi-person-fill-up::before { content: "\f8a5"; } +.bi-person-fill-x::before { content: "\f8a6"; } +.bi-person-gear::before { content: "\f8a7"; } +.bi-person-lock::before { content: "\f8a8"; } +.bi-person-slash::before { content: "\f8a9"; } +.bi-person-up::before { content: "\f8aa"; } +.bi-scooter::before { content: "\f8ab"; } +.bi-taxi-front-fill::before { content: "\f8ac"; } +.bi-taxi-front::before { content: "\f8ad"; } +.bi-amd::before { content: "\f8ae"; } +.bi-database-add::before { content: "\f8af"; } +.bi-database-check::before { content: "\f8b0"; } +.bi-database-dash::before { content: "\f8b1"; } +.bi-database-down::before { content: "\f8b2"; } +.bi-database-exclamation::before { content: "\f8b3"; } +.bi-database-fill-add::before { content: "\f8b4"; } +.bi-database-fill-check::before { content: "\f8b5"; } +.bi-database-fill-dash::before { content: "\f8b6"; } +.bi-database-fill-down::before { content: "\f8b7"; } +.bi-database-fill-exclamation::before { content: "\f8b8"; } +.bi-database-fill-gear::before { content: "\f8b9"; } +.bi-database-fill-lock::before { content: "\f8ba"; } +.bi-database-fill-slash::before { content: "\f8bb"; } +.bi-database-fill-up::before { content: "\f8bc"; } +.bi-database-fill-x::before { content: "\f8bd"; } +.bi-database-fill::before { content: "\f8be"; } +.bi-database-gear::before { content: "\f8bf"; } +.bi-database-lock::before { content: "\f8c0"; } +.bi-database-slash::before { content: "\f8c1"; } +.bi-database-up::before { content: "\f8c2"; } +.bi-database-x::before { content: "\f8c3"; } +.bi-database::before { content: "\f8c4"; } +.bi-houses-fill::before { content: "\f8c5"; } +.bi-houses::before { content: "\f8c6"; } +.bi-nvidia::before { content: "\f8c7"; } +.bi-person-vcard-fill::before { content: "\f8c8"; } +.bi-person-vcard::before { content: "\f8c9"; } +.bi-sina-weibo::before { content: "\f8ca"; } +.bi-tencent-qq::before { content: "\f8cb"; } +.bi-wikipedia::before { content: "\f8cc"; } diff --git a/public/site_libs/bootstrap/bootstrap-icons.woff b/public/site_libs/bootstrap/bootstrap-icons.woff new file mode 100644 index 00000000..18d21d45 Binary files /dev/null and b/public/site_libs/bootstrap/bootstrap-icons.woff differ diff --git a/public/site_libs/bootstrap/bootstrap.min.css b/public/site_libs/bootstrap/bootstrap.min.css new file mode 100644 index 00000000..600dbd9e --- /dev/null +++ b/public/site_libs/bootstrap/bootstrap.min.css @@ -0,0 +1,10 @@ +/*! + * Bootstrap v5.1.3 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */@import"https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@300;400;700&display=swap";:root{--bs-blue: #2780e3;--bs-indigo: #6610f2;--bs-purple: #613d7c;--bs-pink: #e83e8c;--bs-red: #ff0039;--bs-orange: #f0ad4e;--bs-yellow: #ff7518;--bs-green: #3fb618;--bs-teal: #20c997;--bs-cyan: #9954bb;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #373a3c;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #373a3c;--bs-gray-900: #212529;--bs-default: #373a3c;--bs-primary: #2780e3;--bs-secondary: #373a3c;--bs-success: #3fb618;--bs-info: #9954bb;--bs-warning: #ff7518;--bs-danger: #ff0039;--bs-light: #f8f9fa;--bs-dark: #373a3c;--bs-default-rgb: 55, 58, 60;--bs-primary-rgb: 39, 128, 227;--bs-secondary-rgb: 55, 58, 60;--bs-success-rgb: 63, 182, 24;--bs-info-rgb: 153, 84, 187;--bs-warning-rgb: 255, 117, 24;--bs-danger-rgb: 255, 0, 57;--bs-light-rgb: 248, 249, 250;--bs-dark-rgb: 55, 58, 60;--bs-white-rgb: 255, 255, 255;--bs-black-rgb: 0, 0, 0;--bs-body-color-rgb: 55, 58, 60;--bs-body-bg-rgb: 255, 255, 255;--bs-font-sans-serif: "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-root-font-size: 17px;--bs-body-font-family: var(--bs-font-sans-serif);--bs-body-font-size: 1rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #373a3c;--bs-body-bg: #fff}*,*::before,*::after{box-sizing:border-box}:root{font-size:var(--bs-root-font-size)}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h6,.h6,h5,.h5,h4,.h4,h3,.h3,h2,.h2,h1,.h1{margin-top:0;margin-bottom:.5rem;font-weight:400;line-height:1.2}h1,.h1{font-size:calc(1.325rem + 0.9vw)}@media(min-width: 1200px){h1,.h1{font-size:2rem}}h2,.h2{font-size:calc(1.29rem + 0.48vw)}@media(min-width: 1200px){h2,.h2{font-size:1.65rem}}h3,.h3{font-size:calc(1.27rem + 0.24vw)}@media(min-width: 1200px){h3,.h3{font-size:1.45rem}}h4,.h4{font-size:1.25rem}h5,.h5{font-size:1.1rem}h6,.h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title],abbr[data-bs-original-title]{text-decoration:underline dotted;-webkit-text-decoration:underline dotted;-moz-text-decoration:underline dotted;-ms-text-decoration:underline dotted;-o-text-decoration:underline dotted;cursor:help;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem;padding:.625rem 1.25rem;border-left:.25rem solid #e9ecef}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}b,strong{font-weight:bolder}small,.small{font-size:0.875em}mark,.mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:0.75em;line-height:0;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}a{color:#2780e3;text-decoration:underline;-webkit-text-decoration:underline;-moz-text-decoration:underline;-ms-text-decoration:underline;-o-text-decoration:underline}a:hover{color:#1f66b6}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:var(--bs-font-monospace);font-size:1em;direction:ltr /* rtl:ignore */;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:0.875em;color:#000;background-color:#f7f7f7;padding:.5rem;border:1px solid #dee2e6}pre code{background-color:rgba(0,0,0,0);font-size:inherit;color:inherit;word-break:normal}code{font-size:0.875em;color:#9753b8;background-color:#f7f7f7;padding:.125rem .25rem;word-wrap:break-word}a>code{color:inherit}kbd{padding:.4rem .4rem;font-size:0.875em;color:#fff;background-color:#212529}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}thead,tbody,tfoot,tr,td,th{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}input,button,select,optgroup,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button:not(:disabled),[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + 0.3vw);line-height:inherit}@media(min-width: 1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-text,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none !important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:0.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:0.875em;color:#6c757d}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:0.875em;color:#6c757d}.grid{display:grid;grid-template-rows:repeat(var(--bs-rows, 1), 1fr);grid-template-columns:repeat(var(--bs-columns, 12), 1fr);gap:var(--bs-gap, 1.5rem)}.grid .g-col-1{grid-column:auto/span 1}.grid .g-col-2{grid-column:auto/span 2}.grid .g-col-3{grid-column:auto/span 3}.grid .g-col-4{grid-column:auto/span 4}.grid .g-col-5{grid-column:auto/span 5}.grid .g-col-6{grid-column:auto/span 6}.grid .g-col-7{grid-column:auto/span 7}.grid .g-col-8{grid-column:auto/span 8}.grid .g-col-9{grid-column:auto/span 9}.grid .g-col-10{grid-column:auto/span 10}.grid .g-col-11{grid-column:auto/span 11}.grid .g-col-12{grid-column:auto/span 12}.grid .g-start-1{grid-column-start:1}.grid .g-start-2{grid-column-start:2}.grid .g-start-3{grid-column-start:3}.grid .g-start-4{grid-column-start:4}.grid .g-start-5{grid-column-start:5}.grid .g-start-6{grid-column-start:6}.grid .g-start-7{grid-column-start:7}.grid .g-start-8{grid-column-start:8}.grid .g-start-9{grid-column-start:9}.grid .g-start-10{grid-column-start:10}.grid .g-start-11{grid-column-start:11}@media(min-width: 576px){.grid .g-col-sm-1{grid-column:auto/span 1}.grid .g-col-sm-2{grid-column:auto/span 2}.grid .g-col-sm-3{grid-column:auto/span 3}.grid .g-col-sm-4{grid-column:auto/span 4}.grid .g-col-sm-5{grid-column:auto/span 5}.grid .g-col-sm-6{grid-column:auto/span 6}.grid .g-col-sm-7{grid-column:auto/span 7}.grid .g-col-sm-8{grid-column:auto/span 8}.grid .g-col-sm-9{grid-column:auto/span 9}.grid .g-col-sm-10{grid-column:auto/span 10}.grid .g-col-sm-11{grid-column:auto/span 11}.grid .g-col-sm-12{grid-column:auto/span 12}.grid .g-start-sm-1{grid-column-start:1}.grid .g-start-sm-2{grid-column-start:2}.grid .g-start-sm-3{grid-column-start:3}.grid .g-start-sm-4{grid-column-start:4}.grid .g-start-sm-5{grid-column-start:5}.grid .g-start-sm-6{grid-column-start:6}.grid .g-start-sm-7{grid-column-start:7}.grid .g-start-sm-8{grid-column-start:8}.grid .g-start-sm-9{grid-column-start:9}.grid .g-start-sm-10{grid-column-start:10}.grid .g-start-sm-11{grid-column-start:11}}@media(min-width: 768px){.grid .g-col-md-1{grid-column:auto/span 1}.grid .g-col-md-2{grid-column:auto/span 2}.grid .g-col-md-3{grid-column:auto/span 3}.grid .g-col-md-4{grid-column:auto/span 4}.grid .g-col-md-5{grid-column:auto/span 5}.grid .g-col-md-6{grid-column:auto/span 6}.grid .g-col-md-7{grid-column:auto/span 7}.grid .g-col-md-8{grid-column:auto/span 8}.grid .g-col-md-9{grid-column:auto/span 9}.grid .g-col-md-10{grid-column:auto/span 10}.grid .g-col-md-11{grid-column:auto/span 11}.grid .g-col-md-12{grid-column:auto/span 12}.grid .g-start-md-1{grid-column-start:1}.grid .g-start-md-2{grid-column-start:2}.grid .g-start-md-3{grid-column-start:3}.grid .g-start-md-4{grid-column-start:4}.grid .g-start-md-5{grid-column-start:5}.grid .g-start-md-6{grid-column-start:6}.grid .g-start-md-7{grid-column-start:7}.grid .g-start-md-8{grid-column-start:8}.grid .g-start-md-9{grid-column-start:9}.grid .g-start-md-10{grid-column-start:10}.grid .g-start-md-11{grid-column-start:11}}@media(min-width: 992px){.grid .g-col-lg-1{grid-column:auto/span 1}.grid .g-col-lg-2{grid-column:auto/span 2}.grid .g-col-lg-3{grid-column:auto/span 3}.grid .g-col-lg-4{grid-column:auto/span 4}.grid .g-col-lg-5{grid-column:auto/span 5}.grid .g-col-lg-6{grid-column:auto/span 6}.grid .g-col-lg-7{grid-column:auto/span 7}.grid .g-col-lg-8{grid-column:auto/span 8}.grid .g-col-lg-9{grid-column:auto/span 9}.grid .g-col-lg-10{grid-column:auto/span 10}.grid .g-col-lg-11{grid-column:auto/span 11}.grid .g-col-lg-12{grid-column:auto/span 12}.grid .g-start-lg-1{grid-column-start:1}.grid .g-start-lg-2{grid-column-start:2}.grid .g-start-lg-3{grid-column-start:3}.grid .g-start-lg-4{grid-column-start:4}.grid .g-start-lg-5{grid-column-start:5}.grid .g-start-lg-6{grid-column-start:6}.grid .g-start-lg-7{grid-column-start:7}.grid .g-start-lg-8{grid-column-start:8}.grid .g-start-lg-9{grid-column-start:9}.grid .g-start-lg-10{grid-column-start:10}.grid .g-start-lg-11{grid-column-start:11}}@media(min-width: 1200px){.grid .g-col-xl-1{grid-column:auto/span 1}.grid .g-col-xl-2{grid-column:auto/span 2}.grid .g-col-xl-3{grid-column:auto/span 3}.grid .g-col-xl-4{grid-column:auto/span 4}.grid .g-col-xl-5{grid-column:auto/span 5}.grid .g-col-xl-6{grid-column:auto/span 6}.grid .g-col-xl-7{grid-column:auto/span 7}.grid .g-col-xl-8{grid-column:auto/span 8}.grid .g-col-xl-9{grid-column:auto/span 9}.grid .g-col-xl-10{grid-column:auto/span 10}.grid .g-col-xl-11{grid-column:auto/span 11}.grid .g-col-xl-12{grid-column:auto/span 12}.grid .g-start-xl-1{grid-column-start:1}.grid .g-start-xl-2{grid-column-start:2}.grid .g-start-xl-3{grid-column-start:3}.grid .g-start-xl-4{grid-column-start:4}.grid .g-start-xl-5{grid-column-start:5}.grid .g-start-xl-6{grid-column-start:6}.grid .g-start-xl-7{grid-column-start:7}.grid .g-start-xl-8{grid-column-start:8}.grid .g-start-xl-9{grid-column-start:9}.grid .g-start-xl-10{grid-column-start:10}.grid .g-start-xl-11{grid-column-start:11}}@media(min-width: 1400px){.grid .g-col-xxl-1{grid-column:auto/span 1}.grid .g-col-xxl-2{grid-column:auto/span 2}.grid .g-col-xxl-3{grid-column:auto/span 3}.grid .g-col-xxl-4{grid-column:auto/span 4}.grid .g-col-xxl-5{grid-column:auto/span 5}.grid .g-col-xxl-6{grid-column:auto/span 6}.grid .g-col-xxl-7{grid-column:auto/span 7}.grid .g-col-xxl-8{grid-column:auto/span 8}.grid .g-col-xxl-9{grid-column:auto/span 9}.grid .g-col-xxl-10{grid-column:auto/span 10}.grid .g-col-xxl-11{grid-column:auto/span 11}.grid .g-col-xxl-12{grid-column:auto/span 12}.grid .g-start-xxl-1{grid-column-start:1}.grid .g-start-xxl-2{grid-column-start:2}.grid .g-start-xxl-3{grid-column-start:3}.grid .g-start-xxl-4{grid-column-start:4}.grid .g-start-xxl-5{grid-column-start:5}.grid .g-start-xxl-6{grid-column-start:6}.grid .g-start-xxl-7{grid-column-start:7}.grid .g-start-xxl-8{grid-column-start:8}.grid .g-start-xxl-9{grid-column-start:9}.grid .g-start-xxl-10{grid-column-start:10}.grid .g-start-xxl-11{grid-column-start:11}}.table{--bs-table-bg: transparent;--bs-table-accent-bg: transparent;--bs-table-striped-color: #373a3c;--bs-table-striped-bg: rgba(0, 0, 0, 0.05);--bs-table-active-color: #373a3c;--bs-table-active-bg: rgba(0, 0, 0, 0.1);--bs-table-hover-color: #373a3c;--bs-table-hover-bg: rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;color:#373a3c;vertical-align:top;border-color:#dee2e6}.table>:not(caption)>*>*{padding:.5rem .5rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table>:not(:first-child){border-top:2px solid #b6babc}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg: var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg: var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg: var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-bg: #d4e6f9;--bs-table-striped-bg: #c9dbed;--bs-table-striped-color: #000;--bs-table-active-bg: #bfcfe0;--bs-table-active-color: #000;--bs-table-hover-bg: #c4d5e6;--bs-table-hover-color: #000;color:#000;border-color:#bfcfe0}.table-secondary{--bs-table-bg: #d7d8d8;--bs-table-striped-bg: #cccdcd;--bs-table-striped-color: #000;--bs-table-active-bg: #c2c2c2;--bs-table-active-color: #000;--bs-table-hover-bg: #c7c8c8;--bs-table-hover-color: #000;color:#000;border-color:#c2c2c2}.table-success{--bs-table-bg: #d9f0d1;--bs-table-striped-bg: #cee4c7;--bs-table-striped-color: #000;--bs-table-active-bg: #c3d8bc;--bs-table-active-color: #000;--bs-table-hover-bg: #c9dec1;--bs-table-hover-color: #000;color:#000;border-color:#c3d8bc}.table-info{--bs-table-bg: #ebddf1;--bs-table-striped-bg: #dfd2e5;--bs-table-striped-color: #000;--bs-table-active-bg: #d4c7d9;--bs-table-active-color: #000;--bs-table-hover-bg: #d9ccdf;--bs-table-hover-color: #000;color:#000;border-color:#d4c7d9}.table-warning{--bs-table-bg: #ffe3d1;--bs-table-striped-bg: #f2d8c7;--bs-table-striped-color: #000;--bs-table-active-bg: #e6ccbc;--bs-table-active-color: #000;--bs-table-hover-bg: #ecd2c1;--bs-table-hover-color: #000;color:#000;border-color:#e6ccbc}.table-danger{--bs-table-bg: #ffccd7;--bs-table-striped-bg: #f2c2cc;--bs-table-striped-color: #000;--bs-table-active-bg: #e6b8c2;--bs-table-active-color: #000;--bs-table-hover-bg: #ecbdc7;--bs-table-hover-color: #000;color:#000;border-color:#e6b8c2}.table-light{--bs-table-bg: #f8f9fa;--bs-table-striped-bg: #ecedee;--bs-table-striped-color: #000;--bs-table-active-bg: #dfe0e1;--bs-table-active-color: #000;--bs-table-hover-bg: #e5e6e7;--bs-table-hover-color: #000;color:#000;border-color:#dfe0e1}.table-dark{--bs-table-bg: #373a3c;--bs-table-striped-bg: #414446;--bs-table-striped-color: #fff;--bs-table-active-bg: #4b4e50;--bs-table-active-color: #fff;--bs-table-hover-bg: #46494b;--bs-table-hover-color: #fff;color:#fff;border-color:#4b4e50}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width: 575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label,.shiny-input-container .control-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(0.375rem + 1px);padding-bottom:calc(0.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(0.5rem + 1px);padding-bottom:calc(0.5rem + 1px);font-size:1.25rem}.col-form-label-sm{padding-top:calc(0.25rem + 1px);padding-bottom:calc(0.25rem + 1px);font-size:0.875rem}.form-text{margin-top:.25rem;font-size:0.875em;color:#6c757d}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#373a3c;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;border-radius:0;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:#373a3c;background-color:#fff;border-color:#93c0f1;outline:0;box-shadow:0 0 0 .25rem rgba(39,128,227,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}.form-control::file-selector-button{padding:.375rem .75rem;margin:-0.375rem -0.75rem;margin-inline-end:.75rem;color:#373a3c;background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#dde0e3}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-0.375rem -0.75rem;margin-inline-end:.75rem;color:#373a3c;background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-control::-webkit-file-upload-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#dde0e3}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:#373a3c;background-color:rgba(0,0,0,0);border:solid rgba(0,0,0,0);border-width:1px 0}.form-control-plaintext.form-control-sm,.form-control-plaintext.form-control-lg{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + 0.5rem + 2px);padding:.25rem .5rem;font-size:0.875rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-0.25rem -0.5rem;margin-inline-end:.5rem}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-0.25rem -0.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-0.5rem -1rem;margin-inline-end:1rem}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-0.5rem -1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + 0.75rem + 2px)}textarea.form-control-sm{min-height:calc(1.5em + 0.5rem + 2px)}textarea.form-control-lg{min-height:calc(1.5em + 1rem + 2px)}.form-control-color{width:3rem;height:auto;padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{height:1.5em}.form-control-color::-webkit-color-swatch{height:1.5em}.form-select{display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;-moz-padding-start:calc(0.75rem - 3px);font-size:1rem;font-weight:400;line-height:1.5;color:#373a3c;background-color:#fff;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23373a3c' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:1px solid #ced4da;border-radius:0;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none}@media(prefers-reduced-motion: reduce){.form-select{transition:none}}.form-select:focus{border-color:#93c0f1;outline:0;box-shadow:0 0 0 .25rem rgba(39,128,227,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:#e9ecef}.form-select:-moz-focusring{color:rgba(0,0,0,0);text-shadow:0 0 0 #373a3c}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:0.875rem}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.form-check,.shiny-input-container .checkbox,.shiny-input-container .radio{display:block;min-height:1.5rem;padding-left:0;margin-bottom:.125rem}.form-check .form-check-input,.form-check .shiny-input-container .checkbox input,.form-check .shiny-input-container .radio input,.shiny-input-container .checkbox .form-check-input,.shiny-input-container .checkbox .shiny-input-container .checkbox input,.shiny-input-container .checkbox .shiny-input-container .radio input,.shiny-input-container .radio .form-check-input,.shiny-input-container .radio .shiny-input-container .checkbox input,.shiny-input-container .radio .shiny-input-container .radio input{float:left;margin-left:0}.form-check-input,.shiny-input-container .checkbox input,.shiny-input-container .checkbox-inline input,.shiny-input-container .radio input,.shiny-input-container .radio-inline input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:#fff;background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid rgba(0,0,0,.25);appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;color-adjust:exact;-webkit-print-color-adjust:exact}.form-check-input[type=radio],.shiny-input-container .checkbox input[type=radio],.shiny-input-container .checkbox-inline input[type=radio],.shiny-input-container .radio input[type=radio],.shiny-input-container .radio-inline input[type=radio]{border-radius:50%}.form-check-input:active,.shiny-input-container .checkbox input:active,.shiny-input-container .checkbox-inline input:active,.shiny-input-container .radio input:active,.shiny-input-container .radio-inline input:active{filter:brightness(90%)}.form-check-input:focus,.shiny-input-container .checkbox input:focus,.shiny-input-container .checkbox-inline input:focus,.shiny-input-container .radio input:focus,.shiny-input-container .radio-inline input:focus{border-color:#93c0f1;outline:0;box-shadow:0 0 0 .25rem rgba(39,128,227,.25)}.form-check-input:checked,.shiny-input-container .checkbox input:checked,.shiny-input-container .checkbox-inline input:checked,.shiny-input-container .radio input:checked,.shiny-input-container .radio-inline input:checked{background-color:#2780e3;border-color:#2780e3}.form-check-input:checked[type=checkbox],.shiny-input-container .checkbox input:checked[type=checkbox],.shiny-input-container .checkbox-inline input:checked[type=checkbox],.shiny-input-container .radio input:checked[type=checkbox],.shiny-input-container .radio-inline input:checked[type=checkbox]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio],.shiny-input-container .checkbox input:checked[type=radio],.shiny-input-container .checkbox-inline input:checked[type=radio],.shiny-input-container .radio input:checked[type=radio],.shiny-input-container .radio-inline input:checked[type=radio]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate,.shiny-input-container .checkbox input[type=checkbox]:indeterminate,.shiny-input-container .checkbox-inline input[type=checkbox]:indeterminate,.shiny-input-container .radio input[type=checkbox]:indeterminate,.shiny-input-container .radio-inline input[type=checkbox]:indeterminate{background-color:#2780e3;border-color:#2780e3;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled,.shiny-input-container .checkbox input:disabled,.shiny-input-container .checkbox-inline input:disabled,.shiny-input-container .radio input:disabled,.shiny-input-container .radio-inline input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input[disabled]~.form-check-label,.form-check-input[disabled]~span,.form-check-input:disabled~.form-check-label,.form-check-input:disabled~span,.shiny-input-container .checkbox input[disabled]~.form-check-label,.shiny-input-container .checkbox input[disabled]~span,.shiny-input-container .checkbox input:disabled~.form-check-label,.shiny-input-container .checkbox input:disabled~span,.shiny-input-container .checkbox-inline input[disabled]~.form-check-label,.shiny-input-container .checkbox-inline input[disabled]~span,.shiny-input-container .checkbox-inline input:disabled~.form-check-label,.shiny-input-container .checkbox-inline input:disabled~span,.shiny-input-container .radio input[disabled]~.form-check-label,.shiny-input-container .radio input[disabled]~span,.shiny-input-container .radio input:disabled~.form-check-label,.shiny-input-container .radio input:disabled~span,.shiny-input-container .radio-inline input[disabled]~.form-check-label,.shiny-input-container .radio-inline input[disabled]~span,.shiny-input-container .radio-inline input:disabled~.form-check-label,.shiny-input-container .radio-inline input:disabled~span{opacity:.5}.form-check-label,.shiny-input-container .checkbox label,.shiny-input-container .checkbox-inline label,.shiny-input-container .radio label,.shiny-input-container .radio-inline label{cursor:pointer}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");background-position:left center;transition:background-position .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2393c0f1'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-check-inline,.shiny-input-container .checkbox-inline,.shiny-input-container .radio-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.btn-check[disabled]+.btn,.btn-check:disabled+.btn{pointer-events:none;filter:none;opacity:.65}.form-range{width:100%;height:1.5rem;padding:0;background-color:rgba(0,0,0,0);appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(39,128,227,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(39,128,227,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-0.25rem;background-color:#2780e3;border:0;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none}@media(prefers-reduced-motion: reduce){.form-range::-webkit-slider-thumb{transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#bed9f7}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:rgba(0,0,0,0);cursor:pointer;background-color:#dee2e6;border-color:rgba(0,0,0,0)}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#2780e3;border:0;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none}@media(prefers-reduced-motion: reduce){.form-range::-moz-range-thumb{transition:none}}.form-range::-moz-range-thumb:active{background-color:#bed9f7}.form-range::-moz-range-track{width:100%;height:.5rem;color:rgba(0,0,0,0);cursor:pointer;background-color:#dee2e6;border-color:rgba(0,0,0,0)}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;height:100%;padding:1rem .75rem;pointer-events:none;border:1px solid rgba(0,0,0,0);transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media(prefers-reduced-motion: reduce){.form-floating>label{transition:none}}.form-floating>.form-control{padding:1rem .75rem}.form-floating>.form-control::placeholder{color:rgba(0,0,0,0)}.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.input-group{position:relative;display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;align-items:stretch;-webkit-align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-select{position:relative;flex:1 1 auto;-webkit-flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-select:focus{z-index:3}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:3}.input-group-text{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#373a3c;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da}.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text,.input-group-lg>.btn{padding:.5rem 1rem;font-size:1.25rem}.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text,.input-group-sm>.btn{padding:.25rem .5rem;font-size:0.875rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:0.875em;color:#3fb618}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:0.875rem;color:#fff;background-color:rgba(63,182,24,.9)}.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip,.is-valid~.valid-feedback,.is-valid~.valid-tooltip{display:block}.was-validated .form-control:valid,.form-control.is-valid{border-color:#3fb618;padding-right:calc(1.5em + 0.75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%233fb618' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(0.375em + 0.1875rem) center;background-size:calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-control:valid:focus,.form-control.is-valid:focus{border-color:#3fb618;box-shadow:0 0 0 .25rem rgba(63,182,24,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + 0.75rem);background-position:top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem)}.was-validated .form-select:valid,.form-select.is-valid{border-color:#3fb618}.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"],.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23373a3c' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%233fb618' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-select:valid:focus,.form-select.is-valid:focus{border-color:#3fb618;box-shadow:0 0 0 .25rem rgba(63,182,24,.25)}.was-validated .form-check-input:valid,.form-check-input.is-valid{border-color:#3fb618}.was-validated .form-check-input:valid:checked,.form-check-input.is-valid:checked{background-color:#3fb618}.was-validated .form-check-input:valid:focus,.form-check-input.is-valid:focus{box-shadow:0 0 0 .25rem rgba(63,182,24,.25)}.was-validated .form-check-input:valid~.form-check-label,.form-check-input.is-valid~.form-check-label{color:#3fb618}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.was-validated .input-group .form-control:valid,.input-group .form-control.is-valid,.was-validated .input-group .form-select:valid,.input-group .form-select.is-valid{z-index:1}.was-validated .input-group .form-control:valid:focus,.input-group .form-control.is-valid:focus,.was-validated .input-group .form-select:valid:focus,.input-group .form-select.is-valid:focus{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:0.875em;color:#ff0039}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:0.875rem;color:#fff;background-color:rgba(255,0,57,.9)}.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip,.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip{display:block}.was-validated .form-control:invalid,.form-control.is-invalid{border-color:#ff0039;padding-right:calc(1.5em + 0.75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ff0039'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ff0039' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(0.375em + 0.1875rem) center;background-size:calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-control:invalid:focus,.form-control.is-invalid:focus{border-color:#ff0039;box-shadow:0 0 0 .25rem rgba(255,0,57,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + 0.75rem);background-position:top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem)}.was-validated .form-select:invalid,.form-select.is-invalid{border-color:#ff0039}.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"],.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23373a3c' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ff0039'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ff0039' stroke='none'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-select:invalid:focus,.form-select.is-invalid:focus{border-color:#ff0039;box-shadow:0 0 0 .25rem rgba(255,0,57,.25)}.was-validated .form-check-input:invalid,.form-check-input.is-invalid{border-color:#ff0039}.was-validated .form-check-input:invalid:checked,.form-check-input.is-invalid:checked{background-color:#ff0039}.was-validated .form-check-input:invalid:focus,.form-check-input.is-invalid:focus{box-shadow:0 0 0 .25rem rgba(255,0,57,.25)}.was-validated .form-check-input:invalid~.form-check-label,.form-check-input.is-invalid~.form-check-label{color:#ff0039}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.was-validated .input-group .form-control:invalid,.input-group .form-control.is-invalid,.was-validated .input-group .form-select:invalid,.input-group .form-select.is-invalid{z-index:2}.was-validated .input-group .form-control:invalid:focus,.input-group .form-control.is-invalid:focus,.was-validated .input-group .form-select:invalid:focus,.input-group .form-select.is-invalid:focus{z-index:3}.btn{display:inline-block;font-weight:400;line-height:1.5;color:#373a3c;text-align:center;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;vertical-align:middle;cursor:pointer;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;background-color:rgba(0,0,0,0);border:1px solid rgba(0,0,0,0);padding:.375rem .75rem;font-size:1rem;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.btn{transition:none}}.btn:hover{color:#373a3c}.btn-check:focus+.btn,.btn:focus{outline:0;box-shadow:0 0 0 .25rem rgba(39,128,227,.25)}.btn:disabled,.btn.disabled,fieldset:disabled .btn{pointer-events:none;opacity:.65}.btn-default{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-default:hover{color:#fff;background-color:#2f3133;border-color:#2c2e30}.btn-check:focus+.btn-default,.btn-default:focus{color:#fff;background-color:#2f3133;border-color:#2c2e30;box-shadow:0 0 0 .25rem rgba(85,88,89,.5)}.btn-check:checked+.btn-default,.btn-check:active+.btn-default,.btn-default:active,.btn-default.active,.show>.btn-default.dropdown-toggle{color:#fff;background-color:#2c2e30;border-color:#292c2d}.btn-check:checked+.btn-default:focus,.btn-check:active+.btn-default:focus,.btn-default:active:focus,.btn-default.active:focus,.show>.btn-default.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(85,88,89,.5)}.btn-default:disabled,.btn-default.disabled{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-primary{color:#fff;background-color:#2780e3;border-color:#2780e3}.btn-primary:hover{color:#fff;background-color:#216dc1;border-color:#1f66b6}.btn-check:focus+.btn-primary,.btn-primary:focus{color:#fff;background-color:#216dc1;border-color:#1f66b6;box-shadow:0 0 0 .25rem rgba(71,147,231,.5)}.btn-check:checked+.btn-primary,.btn-check:active+.btn-primary,.btn-primary:active,.btn-primary.active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#1f66b6;border-color:#1d60aa}.btn-check:checked+.btn-primary:focus,.btn-check:active+.btn-primary:focus,.btn-primary:active:focus,.btn-primary.active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(71,147,231,.5)}.btn-primary:disabled,.btn-primary.disabled{color:#fff;background-color:#2780e3;border-color:#2780e3}.btn-secondary{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-secondary:hover{color:#fff;background-color:#2f3133;border-color:#2c2e30}.btn-check:focus+.btn-secondary,.btn-secondary:focus{color:#fff;background-color:#2f3133;border-color:#2c2e30;box-shadow:0 0 0 .25rem rgba(85,88,89,.5)}.btn-check:checked+.btn-secondary,.btn-check:active+.btn-secondary,.btn-secondary:active,.btn-secondary.active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#2c2e30;border-color:#292c2d}.btn-check:checked+.btn-secondary:focus,.btn-check:active+.btn-secondary:focus,.btn-secondary:active:focus,.btn-secondary.active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(85,88,89,.5)}.btn-secondary:disabled,.btn-secondary.disabled{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-success{color:#fff;background-color:#3fb618;border-color:#3fb618}.btn-success:hover{color:#fff;background-color:#369b14;border-color:#329213}.btn-check:focus+.btn-success,.btn-success:focus{color:#fff;background-color:#369b14;border-color:#329213;box-shadow:0 0 0 .25rem rgba(92,193,59,.5)}.btn-check:checked+.btn-success,.btn-check:active+.btn-success,.btn-success:active,.btn-success.active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#329213;border-color:#2f8912}.btn-check:checked+.btn-success:focus,.btn-check:active+.btn-success:focus,.btn-success:active:focus,.btn-success.active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(92,193,59,.5)}.btn-success:disabled,.btn-success.disabled{color:#fff;background-color:#3fb618;border-color:#3fb618}.btn-info{color:#fff;background-color:#9954bb;border-color:#9954bb}.btn-info:hover{color:#fff;background-color:#82479f;border-color:#7a4396}.btn-check:focus+.btn-info,.btn-info:focus{color:#fff;background-color:#82479f;border-color:#7a4396;box-shadow:0 0 0 .25rem rgba(168,110,197,.5)}.btn-check:checked+.btn-info,.btn-check:active+.btn-info,.btn-info:active,.btn-info.active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#7a4396;border-color:#733f8c}.btn-check:checked+.btn-info:focus,.btn-check:active+.btn-info:focus,.btn-info:active:focus,.btn-info.active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(168,110,197,.5)}.btn-info:disabled,.btn-info.disabled{color:#fff;background-color:#9954bb;border-color:#9954bb}.btn-warning{color:#fff;background-color:#ff7518;border-color:#ff7518}.btn-warning:hover{color:#fff;background-color:#d96314;border-color:#cc5e13}.btn-check:focus+.btn-warning,.btn-warning:focus{color:#fff;background-color:#d96314;border-color:#cc5e13;box-shadow:0 0 0 .25rem rgba(255,138,59,.5)}.btn-check:checked+.btn-warning,.btn-check:active+.btn-warning,.btn-warning:active,.btn-warning.active,.show>.btn-warning.dropdown-toggle{color:#fff;background-color:#cc5e13;border-color:#bf5812}.btn-check:checked+.btn-warning:focus,.btn-check:active+.btn-warning:focus,.btn-warning:active:focus,.btn-warning.active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(255,138,59,.5)}.btn-warning:disabled,.btn-warning.disabled{color:#fff;background-color:#ff7518;border-color:#ff7518}.btn-danger{color:#fff;background-color:#ff0039;border-color:#ff0039}.btn-danger:hover{color:#fff;background-color:#d90030;border-color:#cc002e}.btn-check:focus+.btn-danger,.btn-danger:focus{color:#fff;background-color:#d90030;border-color:#cc002e;box-shadow:0 0 0 .25rem rgba(255,38,87,.5)}.btn-check:checked+.btn-danger,.btn-check:active+.btn-danger,.btn-danger:active,.btn-danger.active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#cc002e;border-color:#bf002b}.btn-check:checked+.btn-danger:focus,.btn-check:active+.btn-danger:focus,.btn-danger:active:focus,.btn-danger.active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(255,38,87,.5)}.btn-danger:disabled,.btn-danger.disabled{color:#fff;background-color:#ff0039;border-color:#ff0039}.btn-light{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#000;background-color:#f9fafb;border-color:#f9fafb}.btn-check:focus+.btn-light,.btn-light:focus{color:#000;background-color:#f9fafb;border-color:#f9fafb;box-shadow:0 0 0 .25rem rgba(211,212,213,.5)}.btn-check:checked+.btn-light,.btn-check:active+.btn-light,.btn-light:active,.btn-light.active,.show>.btn-light.dropdown-toggle{color:#000;background-color:#f9fafb;border-color:#f9fafb}.btn-check:checked+.btn-light:focus,.btn-check:active+.btn-light:focus,.btn-light:active:focus,.btn-light.active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(211,212,213,.5)}.btn-light:disabled,.btn-light.disabled{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-dark{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-dark:hover{color:#fff;background-color:#2f3133;border-color:#2c2e30}.btn-check:focus+.btn-dark,.btn-dark:focus{color:#fff;background-color:#2f3133;border-color:#2c2e30;box-shadow:0 0 0 .25rem rgba(85,88,89,.5)}.btn-check:checked+.btn-dark,.btn-check:active+.btn-dark,.btn-dark:active,.btn-dark.active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#2c2e30;border-color:#292c2d}.btn-check:checked+.btn-dark:focus,.btn-check:active+.btn-dark:focus,.btn-dark:active:focus,.btn-dark.active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(85,88,89,.5)}.btn-dark:disabled,.btn-dark.disabled{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-outline-default{color:#373a3c;border-color:#373a3c;background-color:rgba(0,0,0,0)}.btn-outline-default:hover{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-check:focus+.btn-outline-default,.btn-outline-default:focus{box-shadow:0 0 0 .25rem rgba(55,58,60,.5)}.btn-check:checked+.btn-outline-default,.btn-check:active+.btn-outline-default,.btn-outline-default:active,.btn-outline-default.active,.btn-outline-default.dropdown-toggle.show{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-check:checked+.btn-outline-default:focus,.btn-check:active+.btn-outline-default:focus,.btn-outline-default:active:focus,.btn-outline-default.active:focus,.btn-outline-default.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(55,58,60,.5)}.btn-outline-default:disabled,.btn-outline-default.disabled{color:#373a3c;background-color:rgba(0,0,0,0)}.btn-outline-primary{color:#2780e3;border-color:#2780e3;background-color:rgba(0,0,0,0)}.btn-outline-primary:hover{color:#fff;background-color:#2780e3;border-color:#2780e3}.btn-check:focus+.btn-outline-primary,.btn-outline-primary:focus{box-shadow:0 0 0 .25rem rgba(39,128,227,.5)}.btn-check:checked+.btn-outline-primary,.btn-check:active+.btn-outline-primary,.btn-outline-primary:active,.btn-outline-primary.active,.btn-outline-primary.dropdown-toggle.show{color:#fff;background-color:#2780e3;border-color:#2780e3}.btn-check:checked+.btn-outline-primary:focus,.btn-check:active+.btn-outline-primary:focus,.btn-outline-primary:active:focus,.btn-outline-primary.active:focus,.btn-outline-primary.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(39,128,227,.5)}.btn-outline-primary:disabled,.btn-outline-primary.disabled{color:#2780e3;background-color:rgba(0,0,0,0)}.btn-outline-secondary{color:#373a3c;border-color:#373a3c;background-color:rgba(0,0,0,0)}.btn-outline-secondary:hover{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-check:focus+.btn-outline-secondary,.btn-outline-secondary:focus{box-shadow:0 0 0 .25rem rgba(55,58,60,.5)}.btn-check:checked+.btn-outline-secondary,.btn-check:active+.btn-outline-secondary,.btn-outline-secondary:active,.btn-outline-secondary.active,.btn-outline-secondary.dropdown-toggle.show{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-check:checked+.btn-outline-secondary:focus,.btn-check:active+.btn-outline-secondary:focus,.btn-outline-secondary:active:focus,.btn-outline-secondary.active:focus,.btn-outline-secondary.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(55,58,60,.5)}.btn-outline-secondary:disabled,.btn-outline-secondary.disabled{color:#373a3c;background-color:rgba(0,0,0,0)}.btn-outline-success{color:#3fb618;border-color:#3fb618;background-color:rgba(0,0,0,0)}.btn-outline-success:hover{color:#fff;background-color:#3fb618;border-color:#3fb618}.btn-check:focus+.btn-outline-success,.btn-outline-success:focus{box-shadow:0 0 0 .25rem rgba(63,182,24,.5)}.btn-check:checked+.btn-outline-success,.btn-check:active+.btn-outline-success,.btn-outline-success:active,.btn-outline-success.active,.btn-outline-success.dropdown-toggle.show{color:#fff;background-color:#3fb618;border-color:#3fb618}.btn-check:checked+.btn-outline-success:focus,.btn-check:active+.btn-outline-success:focus,.btn-outline-success:active:focus,.btn-outline-success.active:focus,.btn-outline-success.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(63,182,24,.5)}.btn-outline-success:disabled,.btn-outline-success.disabled{color:#3fb618;background-color:rgba(0,0,0,0)}.btn-outline-info{color:#9954bb;border-color:#9954bb;background-color:rgba(0,0,0,0)}.btn-outline-info:hover{color:#fff;background-color:#9954bb;border-color:#9954bb}.btn-check:focus+.btn-outline-info,.btn-outline-info:focus{box-shadow:0 0 0 .25rem rgba(153,84,187,.5)}.btn-check:checked+.btn-outline-info,.btn-check:active+.btn-outline-info,.btn-outline-info:active,.btn-outline-info.active,.btn-outline-info.dropdown-toggle.show{color:#fff;background-color:#9954bb;border-color:#9954bb}.btn-check:checked+.btn-outline-info:focus,.btn-check:active+.btn-outline-info:focus,.btn-outline-info:active:focus,.btn-outline-info.active:focus,.btn-outline-info.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(153,84,187,.5)}.btn-outline-info:disabled,.btn-outline-info.disabled{color:#9954bb;background-color:rgba(0,0,0,0)}.btn-outline-warning{color:#ff7518;border-color:#ff7518;background-color:rgba(0,0,0,0)}.btn-outline-warning:hover{color:#fff;background-color:#ff7518;border-color:#ff7518}.btn-check:focus+.btn-outline-warning,.btn-outline-warning:focus{box-shadow:0 0 0 .25rem rgba(255,117,24,.5)}.btn-check:checked+.btn-outline-warning,.btn-check:active+.btn-outline-warning,.btn-outline-warning:active,.btn-outline-warning.active,.btn-outline-warning.dropdown-toggle.show{color:#fff;background-color:#ff7518;border-color:#ff7518}.btn-check:checked+.btn-outline-warning:focus,.btn-check:active+.btn-outline-warning:focus,.btn-outline-warning:active:focus,.btn-outline-warning.active:focus,.btn-outline-warning.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(255,117,24,.5)}.btn-outline-warning:disabled,.btn-outline-warning.disabled{color:#ff7518;background-color:rgba(0,0,0,0)}.btn-outline-danger{color:#ff0039;border-color:#ff0039;background-color:rgba(0,0,0,0)}.btn-outline-danger:hover{color:#fff;background-color:#ff0039;border-color:#ff0039}.btn-check:focus+.btn-outline-danger,.btn-outline-danger:focus{box-shadow:0 0 0 .25rem rgba(255,0,57,.5)}.btn-check:checked+.btn-outline-danger,.btn-check:active+.btn-outline-danger,.btn-outline-danger:active,.btn-outline-danger.active,.btn-outline-danger.dropdown-toggle.show{color:#fff;background-color:#ff0039;border-color:#ff0039}.btn-check:checked+.btn-outline-danger:focus,.btn-check:active+.btn-outline-danger:focus,.btn-outline-danger:active:focus,.btn-outline-danger.active:focus,.btn-outline-danger.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(255,0,57,.5)}.btn-outline-danger:disabled,.btn-outline-danger.disabled{color:#ff0039;background-color:rgba(0,0,0,0)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa;background-color:rgba(0,0,0,0)}.btn-outline-light:hover{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-check:focus+.btn-outline-light,.btn-outline-light:focus{box-shadow:0 0 0 .25rem rgba(248,249,250,.5)}.btn-check:checked+.btn-outline-light,.btn-check:active+.btn-outline-light,.btn-outline-light:active,.btn-outline-light.active,.btn-outline-light.dropdown-toggle.show{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-check:checked+.btn-outline-light:focus,.btn-check:active+.btn-outline-light:focus,.btn-outline-light:active:focus,.btn-outline-light.active:focus,.btn-outline-light.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(248,249,250,.5)}.btn-outline-light:disabled,.btn-outline-light.disabled{color:#f8f9fa;background-color:rgba(0,0,0,0)}.btn-outline-dark{color:#373a3c;border-color:#373a3c;background-color:rgba(0,0,0,0)}.btn-outline-dark:hover{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-check:focus+.btn-outline-dark,.btn-outline-dark:focus{box-shadow:0 0 0 .25rem rgba(55,58,60,.5)}.btn-check:checked+.btn-outline-dark,.btn-check:active+.btn-outline-dark,.btn-outline-dark:active,.btn-outline-dark.active,.btn-outline-dark.dropdown-toggle.show{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-check:checked+.btn-outline-dark:focus,.btn-check:active+.btn-outline-dark:focus,.btn-outline-dark:active:focus,.btn-outline-dark.active:focus,.btn-outline-dark.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(55,58,60,.5)}.btn-outline-dark:disabled,.btn-outline-dark.disabled{color:#373a3c;background-color:rgba(0,0,0,0)}.btn-link{font-weight:400;color:#2780e3;text-decoration:underline;-webkit-text-decoration:underline;-moz-text-decoration:underline;-ms-text-decoration:underline;-o-text-decoration:underline}.btn-link:hover{color:#1f66b6}.btn-link:disabled,.btn-link.disabled{color:#6c757d}.btn-lg,.btn-group-lg>.btn{padding:.5rem 1rem;font-size:1.25rem;border-radius:0}.btn-sm,.btn-group-sm>.btn{padding:.25rem .5rem;font-size:0.875rem;border-radius:0}.fade{transition:opacity .15s linear}@media(prefers-reduced-motion: reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .2s ease}@media(prefers-reduced-motion: reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media(prefers-reduced-motion: reduce){.collapsing.collapse-horizontal{transition:none}}.dropup,.dropend,.dropdown,.dropstart{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid rgba(0,0,0,0);border-bottom:0;border-left:.3em solid rgba(0,0,0,0)}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;z-index:1000;display:none;min-width:10rem;padding:.5rem 0;margin:0;font-size:1rem;color:#373a3c;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:.125rem}.dropdown-menu-start{--bs-position: start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position: end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media(min-width: 576px){.dropdown-menu-sm-start{--bs-position: start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position: end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 768px){.dropdown-menu-md-start{--bs-position: start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position: end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 992px){.dropdown-menu-lg-start{--bs-position: start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position: end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 1200px){.dropdown-menu-xl-start{--bs-position: start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position: end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 1400px){.dropdown-menu-xxl-start{--bs-position: start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position: end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid rgba(0,0,0,0);border-bottom:.3em solid;border-left:.3em solid rgba(0,0,0,0)}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid rgba(0,0,0,0);border-right:0;border-bottom:.3em solid rgba(0,0,0,0);border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid rgba(0,0,0,0);border-right:.3em solid;border-bottom:.3em solid rgba(0,0,0,0)}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid rgba(0,0,0,.15)}.dropdown-item{display:block;width:100%;padding:.25rem 1rem;clear:both;font-weight:400;color:#212529;text-align:inherit;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;white-space:nowrap;background-color:rgba(0,0,0,0);border:0}.dropdown-item:hover,.dropdown-item:focus{color:#1e2125;background-color:#e9ecef}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#2780e3}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:rgba(0,0,0,0)}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1rem;margin-bottom:0;font-size:0.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1rem;color:#212529}.dropdown-menu-dark{color:#dee2e6;background-color:#373a3c;border-color:rgba(0,0,0,.15)}.dropdown-menu-dark .dropdown-item{color:#dee2e6}.dropdown-menu-dark .dropdown-item:hover,.dropdown-menu-dark .dropdown-item:focus{color:#fff;background-color:rgba(255,255,255,.15)}.dropdown-menu-dark .dropdown-item.active,.dropdown-menu-dark .dropdown-item:active{color:#fff;background-color:#2780e3}.dropdown-menu-dark .dropdown-item.disabled,.dropdown-menu-dark .dropdown-item:disabled{color:#adb5bd}.dropdown-menu-dark .dropdown-divider{border-color:rgba(0,0,0,.15)}.dropdown-menu-dark .dropdown-item-text{color:#dee2e6}.dropdown-menu-dark .dropdown-header{color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;flex:1 1 auto;-webkit-flex:1 1 auto}.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn:hover,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn.active{z-index:1}.btn-toolbar{display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;justify-content:flex-start;-webkit-justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:not(:first-child),.btn-group>.btn-group:not(:first-child){margin-left:-1px}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-sm+.dropdown-toggle-split,.btn-group-sm>.btn+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-lg+.dropdown-toggle-split,.btn-group-lg>.btn+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;-webkit-flex-direction:column;align-items:flex-start;-webkit-align-items:flex-start;justify-content:center;-webkit-justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child){margin-top:-1px}.nav{display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem;color:#2780e3;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media(prefers-reduced-motion: reduce){.nav-link{transition:none}}.nav-link:hover,.nav-link:focus{color:#1f66b6}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-link{margin-bottom:-1px;background:none;border:1px solid rgba(0,0,0,0)}.nav-tabs .nav-link:hover,.nav-tabs .nav-link:focus{border-color:#e9ecef #e9ecef #dee2e6;isolation:isolate}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:rgba(0,0,0,0);border-color:rgba(0,0,0,0)}.nav-tabs .nav-link.active,.nav-tabs .nav-item.show .nav-link{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px}.nav-pills .nav-link{background:none;border:0}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#2780e3}.nav-fill>.nav-link,.nav-fill .nav-item{flex:1 1 auto;-webkit-flex:1 1 auto;text-align:center}.nav-justified>.nav-link,.nav-justified .nav-item{flex-basis:0;-webkit-flex-basis:0;flex-grow:1;-webkit-flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between;padding-top:.5rem;padding-bottom:.5rem}.navbar>.container-xxl,.navbar>.container-xl,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container,.navbar>.container-fluid{display:flex;display:-webkit-flex;flex-wrap:inherit;-webkit-flex-wrap:inherit;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between}.navbar-brand{padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;white-space:nowrap}.navbar-nav{display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{flex-basis:100%;-webkit-flex-basis:100%;flex-grow:1;-webkit-flex-grow:1;align-items:center;-webkit-align-items:center}.navbar-toggler{padding:.25 0;font-size:1.25rem;line-height:1;background-color:rgba(0,0,0,0);border:1px solid rgba(0,0,0,0);transition:box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 .25rem}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height, 75vh);overflow-y:auto}@media(min-width: 576px){.navbar-expand-sm{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas-header{display:none}.navbar-expand-sm .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:rgba(0,0,0,0);border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-sm .offcanvas-top,.navbar-expand-sm .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-sm .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 768px){.navbar-expand-md{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas-header{display:none}.navbar-expand-md .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:rgba(0,0,0,0);border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-md .offcanvas-top,.navbar-expand-md .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-md .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 992px){.navbar-expand-lg{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas-header{display:none}.navbar-expand-lg .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:rgba(0,0,0,0);border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-lg .offcanvas-top,.navbar-expand-lg .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-lg .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 1200px){.navbar-expand-xl{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas-header{display:none}.navbar-expand-xl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:rgba(0,0,0,0);border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xl .offcanvas-top,.navbar-expand-xl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xl .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 1400px){.navbar-expand-xxl{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:rgba(0,0,0,0);border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xxl .offcanvas-top,.navbar-expand-xxl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xxl .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas-header{display:none}.navbar-expand .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:rgba(0,0,0,0);border-right:0;border-left:0;transition:none;transform:none}.navbar-expand .offcanvas-top,.navbar-expand .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}.navbar-light{background-color:#f8f9fa}.navbar-light .navbar-brand{color:#545555}.navbar-light .navbar-brand:hover,.navbar-light .navbar-brand:focus{color:#1a5698}.navbar-light .navbar-nav .nav-link{color:#545555}.navbar-light .navbar-nav .nav-link:hover,.navbar-light .navbar-nav .nav-link:focus{color:rgba(26,86,152,.8)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(84,85,85,.75)}.navbar-light .navbar-nav .show>.nav-link,.navbar-light .navbar-nav .nav-link.active{color:#1a5698}.navbar-light .navbar-toggler{color:#545555;border-color:rgba(84,85,85,0)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23545555' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:#545555}.navbar-light .navbar-text a,.navbar-light .navbar-text a:hover,.navbar-light .navbar-text a:focus{color:#1a5698}.navbar-dark{background-color:#f8f9fa}.navbar-dark .navbar-brand{color:#545555}.navbar-dark .navbar-brand:hover,.navbar-dark .navbar-brand:focus{color:#1a5698}.navbar-dark .navbar-nav .nav-link{color:#545555}.navbar-dark .navbar-nav .nav-link:hover,.navbar-dark .navbar-nav .nav-link:focus{color:rgba(26,86,152,.8)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(84,85,85,.75)}.navbar-dark .navbar-nav .show>.nav-link,.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active{color:#1a5698}.navbar-dark .navbar-toggler{color:#545555;border-color:rgba(84,85,85,0)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23545555' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:#545555}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:hover,.navbar-dark .navbar-text a:focus{color:#1a5698}.card{position:relative;display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0}.card>.list-group:last-child{border-bottom-width:0}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;-webkit-flex:1 1 auto;padding:1rem 1rem}.card-title{margin-bottom:.5rem}.card-subtitle{margin-top:-0.25rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:1rem}.card-header{padding:.5rem 1rem;margin-bottom:0;background-color:#adb5bd;border-bottom:1px solid rgba(0,0,0,.125)}.card-footer{padding:.5rem 1rem;background-color:#adb5bd;border-top:1px solid rgba(0,0,0,.125)}.card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem}.card-img,.card-img-top,.card-img-bottom{width:100%}.card-group>.card{margin-bottom:.75rem}@media(min-width: 576px){.card-group{display:flex;display:-webkit-flex;flex-flow:row wrap;-webkit-flex-flow:row wrap}.card-group>.card{flex:1 0 0%;-webkit-flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}}.accordion-button{position:relative;display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;width:100%;padding:1rem 1.25rem;font-size:1rem;color:#373a3c;text-align:left;background-color:#fff;border:0;overflow-anchor:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,border-radius .15s ease}@media(prefers-reduced-motion: reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:#2373cc;background-color:#e9f2fc;box-shadow:inset 0 -1px 0 rgba(0,0,0,.125)}.accordion-button:not(.collapsed)::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%232373cc'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");transform:rotate(-180deg)}.accordion-button::after{flex-shrink:0;-webkit-flex-shrink:0;width:1.25rem;height:1.25rem;margin-left:auto;content:"";background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23373a3c'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-size:1.25rem;transition:transform .2s ease-in-out}@media(prefers-reduced-motion: reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:#93c0f1;outline:0;box-shadow:0 0 0 .25rem rgba(39,128,227,.25)}.accordion-header{margin-bottom:0}.accordion-item{background-color:#fff;border:1px solid rgba(0,0,0,.125)}.accordion-item:not(:first-of-type){border-top:0}.accordion-body{padding:1rem 1.25rem}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.breadcrumb{display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;padding:0 0;margin-bottom:1rem;list-style:none}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:var(--bs-breadcrumb-divider, ">") /* rtl: var(--bs-breadcrumb-divider, ">") */}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;display:-webkit-flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;color:#2780e3;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;background-color:#fff;border:1px solid #dee2e6;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:#1f66b6;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;color:#1f66b6;background-color:#e9ecef;outline:0;box-shadow:0 0 0 .25rem rgba(39,128,227,.25)}.page-item:not(:first-child) .page-link{margin-left:-1px}.page-item.active .page-link{z-index:3;color:#fff;background-color:#2780e3;border-color:#2780e3}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;background-color:#fff;border-color:#dee2e6}.page-link{padding:.375rem .75rem}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:0.875rem}.badge{display:inline-block;padding:.35em .65em;font-size:0.75em;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{position:relative;padding:1rem 1rem;margin-bottom:1rem;border:0 solid rgba(0,0,0,0)}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-default{color:#212324;background-color:#d7d8d8;border-color:#c3c4c5}.alert-default .alert-link{color:#1a1c1d}.alert-primary{color:#174d88;background-color:#d4e6f9;border-color:#bed9f7}.alert-primary .alert-link{color:#123e6d}.alert-secondary{color:#212324;background-color:#d7d8d8;border-color:#c3c4c5}.alert-secondary .alert-link{color:#1a1c1d}.alert-success{color:#266d0e;background-color:#d9f0d1;border-color:#c5e9ba}.alert-success .alert-link{color:#1e570b}.alert-info{color:#5c3270;background-color:#ebddf1;border-color:#e0cceb}.alert-info .alert-link{color:#4a285a}.alert-warning{color:#99460e;background-color:#ffe3d1;border-color:#ffd6ba}.alert-warning .alert-link{color:#7a380b}.alert-danger{color:#902;background-color:#ffccd7;border-color:#ffb3c4}.alert-danger .alert-link{color:#7a001b}.alert-light{color:#959596;background-color:#fefefe;border-color:#fdfdfe}.alert-light .alert-link{color:#777778}.alert-dark{color:#212324;background-color:#d7d8d8;border-color:#c3c4c5}.alert-dark .alert-link{color:#1a1c1d}@keyframes progress-bar-stripes{0%{background-position-x:.5rem}}.progress{display:flex;display:-webkit-flex;height:.5rem;overflow:hidden;font-size:0.75rem;background-color:#e9ecef}.progress-bar{display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;justify-content:center;-webkit-justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#2780e3;transition:width .6s ease}@media(prefers-reduced-motion: reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-size:.5rem .5rem}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media(prefers-reduced-motion: reduce){.progress-bar-animated{animation:none}}.list-group{display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;padding-left:0;margin-bottom:0}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>li::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:hover,.list-group-item-action:focus{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#373a3c;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.5rem 1rem;color:#212529;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#2780e3;border-color:#2780e3}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media(min-width: 576px){.list-group-horizontal-sm{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 768px){.list-group-horizontal-md{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 992px){.list-group-horizontal-lg{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 1200px){.list-group-horizontal-xl{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 1400px){.list-group-horizontal-xxl{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-default{color:#212324;background-color:#d7d8d8}.list-group-item-default.list-group-item-action:hover,.list-group-item-default.list-group-item-action:focus{color:#212324;background-color:#c2c2c2}.list-group-item-default.list-group-item-action.active{color:#fff;background-color:#212324;border-color:#212324}.list-group-item-primary{color:#174d88;background-color:#d4e6f9}.list-group-item-primary.list-group-item-action:hover,.list-group-item-primary.list-group-item-action:focus{color:#174d88;background-color:#bfcfe0}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#174d88;border-color:#174d88}.list-group-item-secondary{color:#212324;background-color:#d7d8d8}.list-group-item-secondary.list-group-item-action:hover,.list-group-item-secondary.list-group-item-action:focus{color:#212324;background-color:#c2c2c2}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#212324;border-color:#212324}.list-group-item-success{color:#266d0e;background-color:#d9f0d1}.list-group-item-success.list-group-item-action:hover,.list-group-item-success.list-group-item-action:focus{color:#266d0e;background-color:#c3d8bc}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#266d0e;border-color:#266d0e}.list-group-item-info{color:#5c3270;background-color:#ebddf1}.list-group-item-info.list-group-item-action:hover,.list-group-item-info.list-group-item-action:focus{color:#5c3270;background-color:#d4c7d9}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#5c3270;border-color:#5c3270}.list-group-item-warning{color:#99460e;background-color:#ffe3d1}.list-group-item-warning.list-group-item-action:hover,.list-group-item-warning.list-group-item-action:focus{color:#99460e;background-color:#e6ccbc}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#99460e;border-color:#99460e}.list-group-item-danger{color:#902;background-color:#ffccd7}.list-group-item-danger.list-group-item-action:hover,.list-group-item-danger.list-group-item-action:focus{color:#902;background-color:#e6b8c2}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#902;border-color:#902}.list-group-item-light{color:#959596;background-color:#fefefe}.list-group-item-light.list-group-item-action:hover,.list-group-item-light.list-group-item-action:focus{color:#959596;background-color:#e5e5e5}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#959596;border-color:#959596}.list-group-item-dark{color:#212324;background-color:#d7d8d8}.list-group-item-dark.list-group-item-action:hover,.list-group-item-dark.list-group-item-action:focus{color:#212324;background-color:#c2c2c2}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#212324;border-color:#212324}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:#000;background:rgba(0,0,0,0) url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;opacity:.5}.btn-close:hover{color:#000;text-decoration:none;opacity:.75}.btn-close:focus{outline:0;box-shadow:0 0 0 .25rem rgba(39,128,227,.25);opacity:1}.btn-close:disabled,.btn-close.disabled{pointer-events:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.toast{width:350px;max-width:100%;font-size:0.875rem;pointer-events:auto;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .5rem 1rem rgba(0,0,0,.15)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{width:max-content;width:-webkit-max-content;width:-moz-max-content;width:-ms-max-content;width:-o-max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:.75rem}.toast-header{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;padding:.5rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-header .btn-close{margin-right:-0.375rem;margin-left:.75rem}.toast-body{padding:.75rem;word-wrap:break-word}.modal{position:fixed;top:0;left:0;z-index:1055;display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0, -50px)}@media(prefers-reduced-motion: reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;min-height:calc(100% - 1rem)}.modal-content{position:relative;display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1050;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;display:-webkit-flex;flex-shrink:0;-webkit-flex-shrink:0;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6}.modal-header .btn-close{padding:.5rem .5rem;margin:-0.5rem -0.5rem -0.5rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;-webkit-flex:1 1 auto;padding:1rem}.modal-footer{display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;flex-shrink:0;-webkit-flex-shrink:0;align-items:center;-webkit-align-items:center;justify-content:flex-end;-webkit-justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6}.modal-footer>*{margin:.25rem}@media(min-width: 576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{height:calc(100% - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-sm{max-width:300px}}@media(min-width: 992px){.modal-lg,.modal-xl{max-width:800px}}@media(min-width: 1200px){.modal-xl{max-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0}.modal-fullscreen .modal-body{overflow-y:auto}@media(max-width: 575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media(max-width: 767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media(max-width: 991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media(max-width: 1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media(max-width: 1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{position:absolute;z-index:1080;display:block;margin:0;font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:0.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .tooltip-arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:rgba(0,0,0,0);border-style:solid}.bs-tooltip-top,.bs-tooltip-auto[data-popper-placement^=top]{padding:.4rem 0}.bs-tooltip-top .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow{bottom:0}.bs-tooltip-top .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before{top:-1px;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-end,.bs-tooltip-auto[data-popper-placement^=right]{padding:0 .4rem}.bs-tooltip-end .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-end .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before{right:-1px;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-bottom,.bs-tooltip-auto[data-popper-placement^=bottom]{padding:.4rem 0}.bs-tooltip-bottom .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow{top:0}.bs-tooltip-bottom .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before{bottom:-1px;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-start,.bs-tooltip-auto[data-popper-placement^=left]{padding:0 .4rem}.bs-tooltip-start .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-start .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before{left:-1px;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000}.popover{position:absolute;top:0;left:0 /* rtl:ignore */;z-index:1070;display:block;max-width:276px;font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:0.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2)}.popover .popover-arrow{position:absolute;display:block;width:1rem;height:.5rem}.popover .popover-arrow::before,.popover .popover-arrow::after{position:absolute;display:block;content:"";border-color:rgba(0,0,0,0);border-style:solid}.bs-popover-top>.popover-arrow,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow{bottom:calc(-0.5rem - 1px)}.bs-popover-top>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-top>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-end>.popover-arrow,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow{left:calc(-0.5rem - 1px);width:.5rem;height:1rem}.bs-popover-end>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-end>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-bottom>.popover-arrow,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow{top:calc(-0.5rem - 1px)}.bs-popover-bottom>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-bottom>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-bottom .popover-header::before,.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-0.5rem;content:"";border-bottom:1px solid #f0f0f0}.bs-popover-start>.popover-arrow,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow{right:calc(-0.5rem - 1px);width:.5rem;height:1rem}.bs-popover-start>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-start>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem 1rem;margin-bottom:0;font-size:1rem;background-color:#f0f0f0;border-bottom:1px solid rgba(0,0,0,.2)}.popover-header:empty{display:none}.popover-body{padding:1rem 1rem;color:#373a3c}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y;-webkit-touch-action:pan-y;-moz-touch-action:pan-y;-ms-touch-action:pan-y;-o-touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;backface-visibility:hidden;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;transition:transform .6s ease-in-out}@media(prefers-reduced-motion: reduce){.carousel-item{transition:none}}.carousel-item.active,.carousel-item-next,.carousel-item-prev{display:block}.carousel-item-next:not(.carousel-item-start),.active.carousel-item-end{transform:translateX(100%)}.carousel-item-prev:not(.carousel-item-end),.active.carousel-item-start{transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item.active,.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end{z-index:1;opacity:1}.carousel-fade .active.carousel-item-start,.carousel-fade .active.carousel-item-end{z-index:0;opacity:0;transition:opacity 0s .6s}@media(prefers-reduced-motion: reduce){.carousel-fade .active.carousel-item-start,.carousel-fade .active.carousel-item-end{transition:none}}.carousel-control-prev,.carousel-control-next{position:absolute;top:0;bottom:0;z-index:1;display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;justify-content:center;-webkit-justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:none;border:0;opacity:.5;transition:opacity .15s ease}@media(prefers-reduced-motion: reduce){.carousel-control-prev,.carousel-control-next{transition:none}}.carousel-control-prev:hover,.carousel-control-prev:focus,.carousel-control-next:hover,.carousel-control-next:focus{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-prev-icon,.carousel-control-next-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;display:-webkit-flex;justify-content:center;-webkit-justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%;list-style:none}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;-webkit-flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid rgba(0,0,0,0);border-bottom:10px solid rgba(0,0,0,0);opacity:.5;transition:opacity .6s ease}@media(prefers-reduced-motion: reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-prev-icon,.carousel-dark .carousel-control-next-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}@keyframes spinner-border{to{transform:rotate(360deg) /* rtl:ignore */}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-0.125em;border:.25em solid currentColor;border-right-color:rgba(0,0,0,0);border-radius:50%;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-0.125em;background-color:currentColor;border-radius:50%;opacity:0;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media(prefers-reduced-motion: reduce){.spinner-border,.spinner-grow{animation-duration:1.5s;-webkit-animation-duration:1.5s;-moz-animation-duration:1.5s;-ms-animation-duration:1.5s;-o-animation-duration:1.5s}}.offcanvas{position:fixed;bottom:0;z-index:1045;display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;max-width:100%;visibility:hidden;background-color:#fff;background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}@media(prefers-reduced-motion: reduce){.offcanvas{transition:none}}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between;padding:1rem 1rem}.offcanvas-header .btn-close{padding:.5rem .5rem;margin-top:-0.5rem;margin-right:-0.5rem;margin-bottom:-0.5rem}.offcanvas-title{margin-bottom:0;line-height:1.5}.offcanvas-body{flex-grow:1;-webkit-flex-grow:1;padding:1rem 1rem;overflow-y:auto}.offcanvas-start{top:0;left:0;width:400px;border-right:1px solid rgba(0,0,0,.2);transform:translateX(-100%)}.offcanvas-end{top:0;right:0;width:400px;border-left:1px solid rgba(0,0,0,.2);transform:translateX(100%)}.offcanvas-top{top:0;right:0;left:0;height:30vh;max-height:100%;border-bottom:1px solid rgba(0,0,0,.2);transform:translateY(-100%)}.offcanvas-bottom{right:0;left:0;height:30vh;max-height:100%;border-top:1px solid rgba(0,0,0,.2);transform:translateY(100%)}.offcanvas.show{transform:none}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentColor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{animation:placeholder-glow 2s ease-in-out infinite}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{mask-image:linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);-webkit-mask-image:linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);mask-size:200% 100%;-webkit-mask-size:200% 100%;animation:placeholder-wave 2s linear infinite}@keyframes placeholder-wave{100%{mask-position:-200% 0%;-webkit-mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.link-default{color:#373a3c}.link-default:hover,.link-default:focus{color:#2c2e30}.link-primary{color:#2780e3}.link-primary:hover,.link-primary:focus{color:#1f66b6}.link-secondary{color:#373a3c}.link-secondary:hover,.link-secondary:focus{color:#2c2e30}.link-success{color:#3fb618}.link-success:hover,.link-success:focus{color:#329213}.link-info{color:#9954bb}.link-info:hover,.link-info:focus{color:#7a4396}.link-warning{color:#ff7518}.link-warning:hover,.link-warning:focus{color:#cc5e13}.link-danger{color:#ff0039}.link-danger:hover,.link-danger:focus{color:#cc002e}.link-light{color:#f8f9fa}.link-light:hover,.link-light:focus{color:#f9fafb}.link-dark{color:#373a3c}.link-dark:hover,.link-dark:focus{color:#2c2e30}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio: 100%}.ratio-4x3{--bs-aspect-ratio: 75%}.ratio-16x9{--bs-aspect-ratio: 56.25%}.ratio-21x9{--bs-aspect-ratio: 42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:sticky;top:0;z-index:1020}@media(min-width: 576px){.sticky-sm-top{position:sticky;top:0;z-index:1020}}@media(min-width: 768px){.sticky-md-top{position:sticky;top:0;z-index:1020}}@media(min-width: 992px){.sticky-lg-top{position:sticky;top:0;z-index:1020}}@media(min-width: 1200px){.sticky-xl-top{position:sticky;top:0;z-index:1020}}@media(min-width: 1400px){.sticky-xxl-top{position:sticky;top:0;z-index:1020}}.hstack{display:flex;display:-webkit-flex;flex-direction:row;-webkit-flex-direction:row;align-items:center;-webkit-align-items:center;align-self:stretch;-webkit-align-self:stretch}.vstack{display:flex;display:-webkit-flex;flex:1 1 auto;-webkit-flex:1 1 auto;flex-direction:column;-webkit-flex-direction:column;align-self:stretch;-webkit-align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;white-space:nowrap !important;border:0 !important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;-webkit-align-self:stretch;width:1px;min-height:1em;background-color:currentColor;opacity:.25}.align-baseline{vertical-align:baseline !important}.align-top{vertical-align:top !important}.align-middle{vertical-align:middle !important}.align-bottom{vertical-align:bottom !important}.align-text-bottom{vertical-align:text-bottom !important}.align-text-top{vertical-align:text-top !important}.float-start{float:left !important}.float-end{float:right !important}.float-none{float:none !important}.opacity-0{opacity:0 !important}.opacity-25{opacity:.25 !important}.opacity-50{opacity:.5 !important}.opacity-75{opacity:.75 !important}.opacity-100{opacity:1 !important}.overflow-auto{overflow:auto !important}.overflow-hidden{overflow:hidden !important}.overflow-visible{overflow:visible !important}.overflow-scroll{overflow:scroll !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display:grid !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15) !important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075) !important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175) !important}.shadow-none{box-shadow:none !important}.position-static{position:static !important}.position-relative{position:relative !important}.position-absolute{position:absolute !important}.position-fixed{position:fixed !important}.position-sticky{position:sticky !important}.top-0{top:0 !important}.top-50{top:50% !important}.top-100{top:100% !important}.bottom-0{bottom:0 !important}.bottom-50{bottom:50% !important}.bottom-100{bottom:100% !important}.start-0{left:0 !important}.start-50{left:50% !important}.start-100{left:100% !important}.end-0{right:0 !important}.end-50{right:50% !important}.end-100{right:100% !important}.translate-middle{transform:translate(-50%, -50%) !important}.translate-middle-x{transform:translateX(-50%) !important}.translate-middle-y{transform:translateY(-50%) !important}.border{border:1px solid #dee2e6 !important}.border-0{border:0 !important}.border-top{border-top:1px solid #dee2e6 !important}.border-top-0{border-top:0 !important}.border-end{border-right:1px solid #dee2e6 !important}.border-end-0{border-right:0 !important}.border-bottom{border-bottom:1px solid #dee2e6 !important}.border-bottom-0{border-bottom:0 !important}.border-start{border-left:1px solid #dee2e6 !important}.border-start-0{border-left:0 !important}.border-default{border-color:#373a3c !important}.border-primary{border-color:#2780e3 !important}.border-secondary{border-color:#373a3c !important}.border-success{border-color:#3fb618 !important}.border-info{border-color:#9954bb !important}.border-warning{border-color:#ff7518 !important}.border-danger{border-color:#ff0039 !important}.border-light{border-color:#f8f9fa !important}.border-dark{border-color:#373a3c !important}.border-white{border-color:#fff !important}.border-1{border-width:1px !important}.border-2{border-width:2px !important}.border-3{border-width:3px !important}.border-4{border-width:4px !important}.border-5{border-width:5px !important}.w-25{width:25% !important}.w-50{width:50% !important}.w-75{width:75% !important}.w-100{width:100% !important}.w-auto{width:auto !important}.mw-100{max-width:100% !important}.vw-100{width:100vw !important}.min-vw-100{min-width:100vw !important}.h-25{height:25% !important}.h-50{height:50% !important}.h-75{height:75% !important}.h-100{height:100% !important}.h-auto{height:auto !important}.mh-100{max-height:100% !important}.vh-100{height:100vh !important}.min-vh-100{min-height:100vh !important}.flex-fill{flex:1 1 auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-0{gap:0 !important}.gap-1{gap:.25rem !important}.gap-2{gap:.5rem !important}.gap-3{gap:1rem !important}.gap-4{gap:1.5rem !important}.gap-5{gap:3rem !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.justify-content-evenly{justify-content:space-evenly !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}.order-first{order:-1 !important}.order-0{order:0 !important}.order-1{order:1 !important}.order-2{order:2 !important}.order-3{order:3 !important}.order-4{order:4 !important}.order-5{order:5 !important}.order-last{order:6 !important}.m-0{margin:0 !important}.m-1{margin:.25rem !important}.m-2{margin:.5rem !important}.m-3{margin:1rem !important}.m-4{margin:1.5rem !important}.m-5{margin:3rem !important}.m-auto{margin:auto !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-3{margin-right:1rem !important;margin-left:1rem !important}.mx-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-5{margin-right:3rem !important;margin-left:3rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-0{margin-top:0 !important}.mt-1{margin-top:.25rem !important}.mt-2{margin-top:.5rem !important}.mt-3{margin-top:1rem !important}.mt-4{margin-top:1.5rem !important}.mt-5{margin-top:3rem !important}.mt-auto{margin-top:auto !important}.me-0{margin-right:0 !important}.me-1{margin-right:.25rem !important}.me-2{margin-right:.5rem !important}.me-3{margin-right:1rem !important}.me-4{margin-right:1.5rem !important}.me-5{margin-right:3rem !important}.me-auto{margin-right:auto !important}.mb-0{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2{margin-bottom:.5rem !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.mb-5{margin-bottom:3rem !important}.mb-auto{margin-bottom:auto !important}.ms-0{margin-left:0 !important}.ms-1{margin-left:.25rem !important}.ms-2{margin-left:.5rem !important}.ms-3{margin-left:1rem !important}.ms-4{margin-left:1.5rem !important}.ms-5{margin-left:3rem !important}.ms-auto{margin-left:auto !important}.p-0{padding:0 !important}.p-1{padding:.25rem !important}.p-2{padding:.5rem !important}.p-3{padding:1rem !important}.p-4{padding:1.5rem !important}.p-5{padding:3rem !important}.px-0{padding-right:0 !important;padding-left:0 !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-3{padding-right:1rem !important;padding-left:1rem !important}.px-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-5{padding-right:3rem !important;padding-left:3rem !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-0{padding-top:0 !important}.pt-1{padding-top:.25rem !important}.pt-2{padding-top:.5rem !important}.pt-3{padding-top:1rem !important}.pt-4{padding-top:1.5rem !important}.pt-5{padding-top:3rem !important}.pe-0{padding-right:0 !important}.pe-1{padding-right:.25rem !important}.pe-2{padding-right:.5rem !important}.pe-3{padding-right:1rem !important}.pe-4{padding-right:1.5rem !important}.pe-5{padding-right:3rem !important}.pb-0{padding-bottom:0 !important}.pb-1{padding-bottom:.25rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.pb-5{padding-bottom:3rem !important}.ps-0{padding-left:0 !important}.ps-1{padding-left:.25rem !important}.ps-2{padding-left:.5rem !important}.ps-3{padding-left:1rem !important}.ps-4{padding-left:1.5rem !important}.ps-5{padding-left:3rem !important}.font-monospace{font-family:var(--bs-font-monospace) !important}.fs-1{font-size:calc(1.325rem + 0.9vw) !important}.fs-2{font-size:calc(1.29rem + 0.48vw) !important}.fs-3{font-size:calc(1.27rem + 0.24vw) !important}.fs-4{font-size:1.25rem !important}.fs-5{font-size:1.1rem !important}.fs-6{font-size:1rem !important}.fst-italic{font-style:italic !important}.fst-normal{font-style:normal !important}.fw-light{font-weight:300 !important}.fw-lighter{font-weight:lighter !important}.fw-normal{font-weight:400 !important}.fw-bold{font-weight:700 !important}.fw-bolder{font-weight:bolder !important}.lh-1{line-height:1 !important}.lh-sm{line-height:1.25 !important}.lh-base{line-height:1.5 !important}.lh-lg{line-height:2 !important}.text-start{text-align:left !important}.text-end{text-align:right !important}.text-center{text-align:center !important}.text-decoration-none{text-decoration:none !important}.text-decoration-underline{text-decoration:underline !important}.text-decoration-line-through{text-decoration:line-through !important}.text-lowercase{text-transform:lowercase !important}.text-uppercase{text-transform:uppercase !important}.text-capitalize{text-transform:capitalize !important}.text-wrap{white-space:normal !important}.text-nowrap{white-space:nowrap !important}.text-break{word-wrap:break-word !important;word-break:break-word !important}.text-default{--bs-text-opacity: 1;color:rgba(var(--bs-default-rgb), var(--bs-text-opacity)) !important}.text-primary{--bs-text-opacity: 1;color:rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important}.text-secondary{--bs-text-opacity: 1;color:rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important}.text-success{--bs-text-opacity: 1;color:rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important}.text-info{--bs-text-opacity: 1;color:rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important}.text-warning{--bs-text-opacity: 1;color:rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important}.text-danger{--bs-text-opacity: 1;color:rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important}.text-light{--bs-text-opacity: 1;color:rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important}.text-dark{--bs-text-opacity: 1;color:rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important}.text-black{--bs-text-opacity: 1;color:rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important}.text-white{--bs-text-opacity: 1;color:rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important}.text-body{--bs-text-opacity: 1;color:rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important}.text-muted{--bs-text-opacity: 1;color:#6c757d !important}.text-black-50{--bs-text-opacity: 1;color:rgba(0,0,0,.5) !important}.text-white-50{--bs-text-opacity: 1;color:rgba(255,255,255,.5) !important}.text-reset{--bs-text-opacity: 1;color:inherit !important}.text-opacity-25{--bs-text-opacity: 0.25}.text-opacity-50{--bs-text-opacity: 0.5}.text-opacity-75{--bs-text-opacity: 0.75}.text-opacity-100{--bs-text-opacity: 1}.bg-default{--bs-bg-opacity: 1;background-color:rgba(var(--bs-default-rgb), var(--bs-bg-opacity)) !important}.bg-primary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important}.bg-secondary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important}.bg-success{--bs-bg-opacity: 1;background-color:rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important}.bg-info{--bs-bg-opacity: 1;background-color:rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important}.bg-warning{--bs-bg-opacity: 1;background-color:rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important}.bg-danger{--bs-bg-opacity: 1;background-color:rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important}.bg-light{--bs-bg-opacity: 1;background-color:rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important}.bg-dark{--bs-bg-opacity: 1;background-color:rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important}.bg-black{--bs-bg-opacity: 1;background-color:rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important}.bg-white{--bs-bg-opacity: 1;background-color:rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important}.bg-body{--bs-bg-opacity: 1;background-color:rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important}.bg-transparent{--bs-bg-opacity: 1;background-color:rgba(0,0,0,0) !important}.bg-opacity-10{--bs-bg-opacity: 0.1}.bg-opacity-25{--bs-bg-opacity: 0.25}.bg-opacity-50{--bs-bg-opacity: 0.5}.bg-opacity-75{--bs-bg-opacity: 0.75}.bg-opacity-100{--bs-bg-opacity: 1}.bg-gradient{background-image:var(--bs-gradient) !important}.user-select-all{user-select:all !important}.user-select-auto{user-select:auto !important}.user-select-none{user-select:none !important}.pe-none{pointer-events:none !important}.pe-auto{pointer-events:auto !important}.rounded{border-radius:.25rem !important}.rounded-0{border-radius:0 !important}.rounded-1{border-radius:.2em !important}.rounded-2{border-radius:.25rem !important}.rounded-3{border-radius:.3rem !important}.rounded-circle{border-radius:50% !important}.rounded-pill{border-radius:50rem !important}.rounded-top{border-top-left-radius:.25rem !important;border-top-right-radius:.25rem !important}.rounded-end{border-top-right-radius:.25rem !important;border-bottom-right-radius:.25rem !important}.rounded-bottom{border-bottom-right-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.rounded-start{border-bottom-left-radius:.25rem !important;border-top-left-radius:.25rem !important}.visible{visibility:visible !important}.invisible{visibility:hidden !important}@media(min-width: 576px){.float-sm-start{float:left !important}.float-sm-end{float:right !important}.float-sm-none{float:none !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-grid{display:grid !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-sm-0{gap:0 !important}.gap-sm-1{gap:.25rem !important}.gap-sm-2{gap:.5rem !important}.gap-sm-3{gap:1rem !important}.gap-sm-4{gap:1.5rem !important}.gap-sm-5{gap:3rem !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.justify-content-sm-evenly{justify-content:space-evenly !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}.order-sm-first{order:-1 !important}.order-sm-0{order:0 !important}.order-sm-1{order:1 !important}.order-sm-2{order:2 !important}.order-sm-3{order:3 !important}.order-sm-4{order:4 !important}.order-sm-5{order:5 !important}.order-sm-last{order:6 !important}.m-sm-0{margin:0 !important}.m-sm-1{margin:.25rem !important}.m-sm-2{margin:.5rem !important}.m-sm-3{margin:1rem !important}.m-sm-4{margin:1.5rem !important}.m-sm-5{margin:3rem !important}.m-sm-auto{margin:auto !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-sm-3{margin-right:1rem !important;margin-left:1rem !important}.mx-sm-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-sm-5{margin-right:3rem !important;margin-left:3rem !important}.mx-sm-auto{margin-right:auto !important;margin-left:auto !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-sm-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-sm-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-sm-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-sm-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-sm-0{margin-top:0 !important}.mt-sm-1{margin-top:.25rem !important}.mt-sm-2{margin-top:.5rem !important}.mt-sm-3{margin-top:1rem !important}.mt-sm-4{margin-top:1.5rem !important}.mt-sm-5{margin-top:3rem !important}.mt-sm-auto{margin-top:auto !important}.me-sm-0{margin-right:0 !important}.me-sm-1{margin-right:.25rem !important}.me-sm-2{margin-right:.5rem !important}.me-sm-3{margin-right:1rem !important}.me-sm-4{margin-right:1.5rem !important}.me-sm-5{margin-right:3rem !important}.me-sm-auto{margin-right:auto !important}.mb-sm-0{margin-bottom:0 !important}.mb-sm-1{margin-bottom:.25rem !important}.mb-sm-2{margin-bottom:.5rem !important}.mb-sm-3{margin-bottom:1rem !important}.mb-sm-4{margin-bottom:1.5rem !important}.mb-sm-5{margin-bottom:3rem !important}.mb-sm-auto{margin-bottom:auto !important}.ms-sm-0{margin-left:0 !important}.ms-sm-1{margin-left:.25rem !important}.ms-sm-2{margin-left:.5rem !important}.ms-sm-3{margin-left:1rem !important}.ms-sm-4{margin-left:1.5rem !important}.ms-sm-5{margin-left:3rem !important}.ms-sm-auto{margin-left:auto !important}.p-sm-0{padding:0 !important}.p-sm-1{padding:.25rem !important}.p-sm-2{padding:.5rem !important}.p-sm-3{padding:1rem !important}.p-sm-4{padding:1.5rem !important}.p-sm-5{padding:3rem !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-sm-3{padding-right:1rem !important;padding-left:1rem !important}.px-sm-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-sm-5{padding-right:3rem !important;padding-left:3rem !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-sm-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-sm-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-sm-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-sm-0{padding-top:0 !important}.pt-sm-1{padding-top:.25rem !important}.pt-sm-2{padding-top:.5rem !important}.pt-sm-3{padding-top:1rem !important}.pt-sm-4{padding-top:1.5rem !important}.pt-sm-5{padding-top:3rem !important}.pe-sm-0{padding-right:0 !important}.pe-sm-1{padding-right:.25rem !important}.pe-sm-2{padding-right:.5rem !important}.pe-sm-3{padding-right:1rem !important}.pe-sm-4{padding-right:1.5rem !important}.pe-sm-5{padding-right:3rem !important}.pb-sm-0{padding-bottom:0 !important}.pb-sm-1{padding-bottom:.25rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pb-sm-3{padding-bottom:1rem !important}.pb-sm-4{padding-bottom:1.5rem !important}.pb-sm-5{padding-bottom:3rem !important}.ps-sm-0{padding-left:0 !important}.ps-sm-1{padding-left:.25rem !important}.ps-sm-2{padding-left:.5rem !important}.ps-sm-3{padding-left:1rem !important}.ps-sm-4{padding-left:1.5rem !important}.ps-sm-5{padding-left:3rem !important}.text-sm-start{text-align:left !important}.text-sm-end{text-align:right !important}.text-sm-center{text-align:center !important}}@media(min-width: 768px){.float-md-start{float:left !important}.float-md-end{float:right !important}.float-md-none{float:none !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-grid{display:grid !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-md-0{gap:0 !important}.gap-md-1{gap:.25rem !important}.gap-md-2{gap:.5rem !important}.gap-md-3{gap:1rem !important}.gap-md-4{gap:1.5rem !important}.gap-md-5{gap:3rem !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.justify-content-md-evenly{justify-content:space-evenly !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}.order-md-first{order:-1 !important}.order-md-0{order:0 !important}.order-md-1{order:1 !important}.order-md-2{order:2 !important}.order-md-3{order:3 !important}.order-md-4{order:4 !important}.order-md-5{order:5 !important}.order-md-last{order:6 !important}.m-md-0{margin:0 !important}.m-md-1{margin:.25rem !important}.m-md-2{margin:.5rem !important}.m-md-3{margin:1rem !important}.m-md-4{margin:1.5rem !important}.m-md-5{margin:3rem !important}.m-md-auto{margin:auto !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-md-3{margin-right:1rem !important;margin-left:1rem !important}.mx-md-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-md-5{margin-right:3rem !important;margin-left:3rem !important}.mx-md-auto{margin-right:auto !important;margin-left:auto !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-md-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-md-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-md-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-md-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-md-0{margin-top:0 !important}.mt-md-1{margin-top:.25rem !important}.mt-md-2{margin-top:.5rem !important}.mt-md-3{margin-top:1rem !important}.mt-md-4{margin-top:1.5rem !important}.mt-md-5{margin-top:3rem !important}.mt-md-auto{margin-top:auto !important}.me-md-0{margin-right:0 !important}.me-md-1{margin-right:.25rem !important}.me-md-2{margin-right:.5rem !important}.me-md-3{margin-right:1rem !important}.me-md-4{margin-right:1.5rem !important}.me-md-5{margin-right:3rem !important}.me-md-auto{margin-right:auto !important}.mb-md-0{margin-bottom:0 !important}.mb-md-1{margin-bottom:.25rem !important}.mb-md-2{margin-bottom:.5rem !important}.mb-md-3{margin-bottom:1rem !important}.mb-md-4{margin-bottom:1.5rem !important}.mb-md-5{margin-bottom:3rem !important}.mb-md-auto{margin-bottom:auto !important}.ms-md-0{margin-left:0 !important}.ms-md-1{margin-left:.25rem !important}.ms-md-2{margin-left:.5rem !important}.ms-md-3{margin-left:1rem !important}.ms-md-4{margin-left:1.5rem !important}.ms-md-5{margin-left:3rem !important}.ms-md-auto{margin-left:auto !important}.p-md-0{padding:0 !important}.p-md-1{padding:.25rem !important}.p-md-2{padding:.5rem !important}.p-md-3{padding:1rem !important}.p-md-4{padding:1.5rem !important}.p-md-5{padding:3rem !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-md-3{padding-right:1rem !important;padding-left:1rem !important}.px-md-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-md-5{padding-right:3rem !important;padding-left:3rem !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-md-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-md-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-md-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-md-0{padding-top:0 !important}.pt-md-1{padding-top:.25rem !important}.pt-md-2{padding-top:.5rem !important}.pt-md-3{padding-top:1rem !important}.pt-md-4{padding-top:1.5rem !important}.pt-md-5{padding-top:3rem !important}.pe-md-0{padding-right:0 !important}.pe-md-1{padding-right:.25rem !important}.pe-md-2{padding-right:.5rem !important}.pe-md-3{padding-right:1rem !important}.pe-md-4{padding-right:1.5rem !important}.pe-md-5{padding-right:3rem !important}.pb-md-0{padding-bottom:0 !important}.pb-md-1{padding-bottom:.25rem !important}.pb-md-2{padding-bottom:.5rem !important}.pb-md-3{padding-bottom:1rem !important}.pb-md-4{padding-bottom:1.5rem !important}.pb-md-5{padding-bottom:3rem !important}.ps-md-0{padding-left:0 !important}.ps-md-1{padding-left:.25rem !important}.ps-md-2{padding-left:.5rem !important}.ps-md-3{padding-left:1rem !important}.ps-md-4{padding-left:1.5rem !important}.ps-md-5{padding-left:3rem !important}.text-md-start{text-align:left !important}.text-md-end{text-align:right !important}.text-md-center{text-align:center !important}}@media(min-width: 992px){.float-lg-start{float:left !important}.float-lg-end{float:right !important}.float-lg-none{float:none !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-grid{display:grid !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-lg-0{gap:0 !important}.gap-lg-1{gap:.25rem !important}.gap-lg-2{gap:.5rem !important}.gap-lg-3{gap:1rem !important}.gap-lg-4{gap:1.5rem !important}.gap-lg-5{gap:3rem !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.justify-content-lg-evenly{justify-content:space-evenly !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}.order-lg-first{order:-1 !important}.order-lg-0{order:0 !important}.order-lg-1{order:1 !important}.order-lg-2{order:2 !important}.order-lg-3{order:3 !important}.order-lg-4{order:4 !important}.order-lg-5{order:5 !important}.order-lg-last{order:6 !important}.m-lg-0{margin:0 !important}.m-lg-1{margin:.25rem !important}.m-lg-2{margin:.5rem !important}.m-lg-3{margin:1rem !important}.m-lg-4{margin:1.5rem !important}.m-lg-5{margin:3rem !important}.m-lg-auto{margin:auto !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-lg-3{margin-right:1rem !important;margin-left:1rem !important}.mx-lg-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-lg-5{margin-right:3rem !important;margin-left:3rem !important}.mx-lg-auto{margin-right:auto !important;margin-left:auto !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-lg-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-lg-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-lg-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-lg-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-lg-0{margin-top:0 !important}.mt-lg-1{margin-top:.25rem !important}.mt-lg-2{margin-top:.5rem !important}.mt-lg-3{margin-top:1rem !important}.mt-lg-4{margin-top:1.5rem !important}.mt-lg-5{margin-top:3rem !important}.mt-lg-auto{margin-top:auto !important}.me-lg-0{margin-right:0 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-2{margin-right:.5rem !important}.me-lg-3{margin-right:1rem !important}.me-lg-4{margin-right:1.5rem !important}.me-lg-5{margin-right:3rem !important}.me-lg-auto{margin-right:auto !important}.mb-lg-0{margin-bottom:0 !important}.mb-lg-1{margin-bottom:.25rem !important}.mb-lg-2{margin-bottom:.5rem !important}.mb-lg-3{margin-bottom:1rem !important}.mb-lg-4{margin-bottom:1.5rem !important}.mb-lg-5{margin-bottom:3rem !important}.mb-lg-auto{margin-bottom:auto !important}.ms-lg-0{margin-left:0 !important}.ms-lg-1{margin-left:.25rem !important}.ms-lg-2{margin-left:.5rem !important}.ms-lg-3{margin-left:1rem !important}.ms-lg-4{margin-left:1.5rem !important}.ms-lg-5{margin-left:3rem !important}.ms-lg-auto{margin-left:auto !important}.p-lg-0{padding:0 !important}.p-lg-1{padding:.25rem !important}.p-lg-2{padding:.5rem !important}.p-lg-3{padding:1rem !important}.p-lg-4{padding:1.5rem !important}.p-lg-5{padding:3rem !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-lg-3{padding-right:1rem !important;padding-left:1rem !important}.px-lg-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-lg-5{padding-right:3rem !important;padding-left:3rem !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-lg-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-lg-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-lg-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-lg-0{padding-top:0 !important}.pt-lg-1{padding-top:.25rem !important}.pt-lg-2{padding-top:.5rem !important}.pt-lg-3{padding-top:1rem !important}.pt-lg-4{padding-top:1.5rem !important}.pt-lg-5{padding-top:3rem !important}.pe-lg-0{padding-right:0 !important}.pe-lg-1{padding-right:.25rem !important}.pe-lg-2{padding-right:.5rem !important}.pe-lg-3{padding-right:1rem !important}.pe-lg-4{padding-right:1.5rem !important}.pe-lg-5{padding-right:3rem !important}.pb-lg-0{padding-bottom:0 !important}.pb-lg-1{padding-bottom:.25rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pb-lg-3{padding-bottom:1rem !important}.pb-lg-4{padding-bottom:1.5rem !important}.pb-lg-5{padding-bottom:3rem !important}.ps-lg-0{padding-left:0 !important}.ps-lg-1{padding-left:.25rem !important}.ps-lg-2{padding-left:.5rem !important}.ps-lg-3{padding-left:1rem !important}.ps-lg-4{padding-left:1.5rem !important}.ps-lg-5{padding-left:3rem !important}.text-lg-start{text-align:left !important}.text-lg-end{text-align:right !important}.text-lg-center{text-align:center !important}}@media(min-width: 1200px){.float-xl-start{float:left !important}.float-xl-end{float:right !important}.float-xl-none{float:none !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-grid{display:grid !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-xl-0{gap:0 !important}.gap-xl-1{gap:.25rem !important}.gap-xl-2{gap:.5rem !important}.gap-xl-3{gap:1rem !important}.gap-xl-4{gap:1.5rem !important}.gap-xl-5{gap:3rem !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.justify-content-xl-evenly{justify-content:space-evenly !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}.order-xl-first{order:-1 !important}.order-xl-0{order:0 !important}.order-xl-1{order:1 !important}.order-xl-2{order:2 !important}.order-xl-3{order:3 !important}.order-xl-4{order:4 !important}.order-xl-5{order:5 !important}.order-xl-last{order:6 !important}.m-xl-0{margin:0 !important}.m-xl-1{margin:.25rem !important}.m-xl-2{margin:.5rem !important}.m-xl-3{margin:1rem !important}.m-xl-4{margin:1.5rem !important}.m-xl-5{margin:3rem !important}.m-xl-auto{margin:auto !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xl-0{margin-top:0 !important}.mt-xl-1{margin-top:.25rem !important}.mt-xl-2{margin-top:.5rem !important}.mt-xl-3{margin-top:1rem !important}.mt-xl-4{margin-top:1.5rem !important}.mt-xl-5{margin-top:3rem !important}.mt-xl-auto{margin-top:auto !important}.me-xl-0{margin-right:0 !important}.me-xl-1{margin-right:.25rem !important}.me-xl-2{margin-right:.5rem !important}.me-xl-3{margin-right:1rem !important}.me-xl-4{margin-right:1.5rem !important}.me-xl-5{margin-right:3rem !important}.me-xl-auto{margin-right:auto !important}.mb-xl-0{margin-bottom:0 !important}.mb-xl-1{margin-bottom:.25rem !important}.mb-xl-2{margin-bottom:.5rem !important}.mb-xl-3{margin-bottom:1rem !important}.mb-xl-4{margin-bottom:1.5rem !important}.mb-xl-5{margin-bottom:3rem !important}.mb-xl-auto{margin-bottom:auto !important}.ms-xl-0{margin-left:0 !important}.ms-xl-1{margin-left:.25rem !important}.ms-xl-2{margin-left:.5rem !important}.ms-xl-3{margin-left:1rem !important}.ms-xl-4{margin-left:1.5rem !important}.ms-xl-5{margin-left:3rem !important}.ms-xl-auto{margin-left:auto !important}.p-xl-0{padding:0 !important}.p-xl-1{padding:.25rem !important}.p-xl-2{padding:.5rem !important}.p-xl-3{padding:1rem !important}.p-xl-4{padding:1.5rem !important}.p-xl-5{padding:3rem !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xl-0{padding-top:0 !important}.pt-xl-1{padding-top:.25rem !important}.pt-xl-2{padding-top:.5rem !important}.pt-xl-3{padding-top:1rem !important}.pt-xl-4{padding-top:1.5rem !important}.pt-xl-5{padding-top:3rem !important}.pe-xl-0{padding-right:0 !important}.pe-xl-1{padding-right:.25rem !important}.pe-xl-2{padding-right:.5rem !important}.pe-xl-3{padding-right:1rem !important}.pe-xl-4{padding-right:1.5rem !important}.pe-xl-5{padding-right:3rem !important}.pb-xl-0{padding-bottom:0 !important}.pb-xl-1{padding-bottom:.25rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pb-xl-3{padding-bottom:1rem !important}.pb-xl-4{padding-bottom:1.5rem !important}.pb-xl-5{padding-bottom:3rem !important}.ps-xl-0{padding-left:0 !important}.ps-xl-1{padding-left:.25rem !important}.ps-xl-2{padding-left:.5rem !important}.ps-xl-3{padding-left:1rem !important}.ps-xl-4{padding-left:1.5rem !important}.ps-xl-5{padding-left:3rem !important}.text-xl-start{text-align:left !important}.text-xl-end{text-align:right !important}.text-xl-center{text-align:center !important}}@media(min-width: 1400px){.float-xxl-start{float:left !important}.float-xxl-end{float:right !important}.float-xxl-none{float:none !important}.d-xxl-inline{display:inline !important}.d-xxl-inline-block{display:inline-block !important}.d-xxl-block{display:block !important}.d-xxl-grid{display:grid !important}.d-xxl-table{display:table !important}.d-xxl-table-row{display:table-row !important}.d-xxl-table-cell{display:table-cell !important}.d-xxl-flex{display:flex !important}.d-xxl-inline-flex{display:inline-flex !important}.d-xxl-none{display:none !important}.flex-xxl-fill{flex:1 1 auto !important}.flex-xxl-row{flex-direction:row !important}.flex-xxl-column{flex-direction:column !important}.flex-xxl-row-reverse{flex-direction:row-reverse !important}.flex-xxl-column-reverse{flex-direction:column-reverse !important}.flex-xxl-grow-0{flex-grow:0 !important}.flex-xxl-grow-1{flex-grow:1 !important}.flex-xxl-shrink-0{flex-shrink:0 !important}.flex-xxl-shrink-1{flex-shrink:1 !important}.flex-xxl-wrap{flex-wrap:wrap !important}.flex-xxl-nowrap{flex-wrap:nowrap !important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-xxl-0{gap:0 !important}.gap-xxl-1{gap:.25rem !important}.gap-xxl-2{gap:.5rem !important}.gap-xxl-3{gap:1rem !important}.gap-xxl-4{gap:1.5rem !important}.gap-xxl-5{gap:3rem !important}.justify-content-xxl-start{justify-content:flex-start !important}.justify-content-xxl-end{justify-content:flex-end !important}.justify-content-xxl-center{justify-content:center !important}.justify-content-xxl-between{justify-content:space-between !important}.justify-content-xxl-around{justify-content:space-around !important}.justify-content-xxl-evenly{justify-content:space-evenly !important}.align-items-xxl-start{align-items:flex-start !important}.align-items-xxl-end{align-items:flex-end !important}.align-items-xxl-center{align-items:center !important}.align-items-xxl-baseline{align-items:baseline !important}.align-items-xxl-stretch{align-items:stretch !important}.align-content-xxl-start{align-content:flex-start !important}.align-content-xxl-end{align-content:flex-end !important}.align-content-xxl-center{align-content:center !important}.align-content-xxl-between{align-content:space-between !important}.align-content-xxl-around{align-content:space-around !important}.align-content-xxl-stretch{align-content:stretch !important}.align-self-xxl-auto{align-self:auto !important}.align-self-xxl-start{align-self:flex-start !important}.align-self-xxl-end{align-self:flex-end !important}.align-self-xxl-center{align-self:center !important}.align-self-xxl-baseline{align-self:baseline !important}.align-self-xxl-stretch{align-self:stretch !important}.order-xxl-first{order:-1 !important}.order-xxl-0{order:0 !important}.order-xxl-1{order:1 !important}.order-xxl-2{order:2 !important}.order-xxl-3{order:3 !important}.order-xxl-4{order:4 !important}.order-xxl-5{order:5 !important}.order-xxl-last{order:6 !important}.m-xxl-0{margin:0 !important}.m-xxl-1{margin:.25rem !important}.m-xxl-2{margin:.5rem !important}.m-xxl-3{margin:1rem !important}.m-xxl-4{margin:1.5rem !important}.m-xxl-5{margin:3rem !important}.m-xxl-auto{margin:auto !important}.mx-xxl-0{margin-right:0 !important;margin-left:0 !important}.mx-xxl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xxl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xxl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xxl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xxl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xxl-auto{margin-right:auto !important;margin-left:auto !important}.my-xxl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xxl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xxl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xxl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xxl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xxl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xxl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xxl-0{margin-top:0 !important}.mt-xxl-1{margin-top:.25rem !important}.mt-xxl-2{margin-top:.5rem !important}.mt-xxl-3{margin-top:1rem !important}.mt-xxl-4{margin-top:1.5rem !important}.mt-xxl-5{margin-top:3rem !important}.mt-xxl-auto{margin-top:auto !important}.me-xxl-0{margin-right:0 !important}.me-xxl-1{margin-right:.25rem !important}.me-xxl-2{margin-right:.5rem !important}.me-xxl-3{margin-right:1rem !important}.me-xxl-4{margin-right:1.5rem !important}.me-xxl-5{margin-right:3rem !important}.me-xxl-auto{margin-right:auto !important}.mb-xxl-0{margin-bottom:0 !important}.mb-xxl-1{margin-bottom:.25rem !important}.mb-xxl-2{margin-bottom:.5rem !important}.mb-xxl-3{margin-bottom:1rem !important}.mb-xxl-4{margin-bottom:1.5rem !important}.mb-xxl-5{margin-bottom:3rem !important}.mb-xxl-auto{margin-bottom:auto !important}.ms-xxl-0{margin-left:0 !important}.ms-xxl-1{margin-left:.25rem !important}.ms-xxl-2{margin-left:.5rem !important}.ms-xxl-3{margin-left:1rem !important}.ms-xxl-4{margin-left:1.5rem !important}.ms-xxl-5{margin-left:3rem !important}.ms-xxl-auto{margin-left:auto !important}.p-xxl-0{padding:0 !important}.p-xxl-1{padding:.25rem !important}.p-xxl-2{padding:.5rem !important}.p-xxl-3{padding:1rem !important}.p-xxl-4{padding:1.5rem !important}.p-xxl-5{padding:3rem !important}.px-xxl-0{padding-right:0 !important;padding-left:0 !important}.px-xxl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xxl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xxl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xxl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xxl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xxl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xxl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xxl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xxl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xxl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xxl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xxl-0{padding-top:0 !important}.pt-xxl-1{padding-top:.25rem !important}.pt-xxl-2{padding-top:.5rem !important}.pt-xxl-3{padding-top:1rem !important}.pt-xxl-4{padding-top:1.5rem !important}.pt-xxl-5{padding-top:3rem !important}.pe-xxl-0{padding-right:0 !important}.pe-xxl-1{padding-right:.25rem !important}.pe-xxl-2{padding-right:.5rem !important}.pe-xxl-3{padding-right:1rem !important}.pe-xxl-4{padding-right:1.5rem !important}.pe-xxl-5{padding-right:3rem !important}.pb-xxl-0{padding-bottom:0 !important}.pb-xxl-1{padding-bottom:.25rem !important}.pb-xxl-2{padding-bottom:.5rem !important}.pb-xxl-3{padding-bottom:1rem !important}.pb-xxl-4{padding-bottom:1.5rem !important}.pb-xxl-5{padding-bottom:3rem !important}.ps-xxl-0{padding-left:0 !important}.ps-xxl-1{padding-left:.25rem !important}.ps-xxl-2{padding-left:.5rem !important}.ps-xxl-3{padding-left:1rem !important}.ps-xxl-4{padding-left:1.5rem !important}.ps-xxl-5{padding-left:3rem !important}.text-xxl-start{text-align:left !important}.text-xxl-end{text-align:right !important}.text-xxl-center{text-align:center !important}}.bg-default{color:#fff}.bg-primary{color:#fff}.bg-secondary{color:#fff}.bg-success{color:#fff}.bg-info{color:#fff}.bg-warning{color:#fff}.bg-danger{color:#fff}.bg-light{color:#000}.bg-dark{color:#fff}@media(min-width: 1200px){.fs-1{font-size:2rem !important}.fs-2{font-size:1.65rem !important}.fs-3{font-size:1.45rem !important}}@media print{.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-grid{display:grid !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}.d-print-none{display:none !important}}.sidebar-item .chapter-number{color:#373a3c}.quarto-container{min-height:calc(100vh - 132px)}footer.footer .nav-footer,#quarto-header>nav{padding-left:1em;padding-right:1em}nav[role=doc-toc]{padding-left:.5em}#quarto-content>*{padding-top:14px}@media(max-width: 991.98px){#quarto-content>*{padding-top:0}#quarto-content .subtitle{padding-top:14px}#quarto-content section:first-of-type h2:first-of-type,#quarto-content section:first-of-type .h2:first-of-type{margin-top:1rem}}.headroom-target,header.headroom{will-change:transform;transition:position 200ms linear;transition:all 200ms linear}header.headroom--pinned{transform:translateY(0%)}header.headroom--unpinned{transform:translateY(-100%)}.navbar-container{width:100%}.navbar-brand{overflow:hidden;text-overflow:ellipsis}.navbar-brand-container{max-width:calc(100% - 115px);min-width:0;display:flex;align-items:center}@media(min-width: 992px){.navbar-brand-container{margin-right:1em}}.navbar-brand.navbar-brand-logo{margin-right:4px;display:inline-flex}.navbar-toggler{flex-basis:content;flex-shrink:0}.navbar .navbar-toggler{order:-1;margin-right:.5em}.navbar-logo{max-height:24px;width:auto;padding-right:4px}nav .nav-item:not(.compact){padding-top:1px}nav .nav-link i,nav .dropdown-item i{padding-right:1px}.navbar-expand-lg .navbar-nav .nav-link{padding-left:.6rem;padding-right:.6rem}nav .nav-item.compact .nav-link{padding-left:.5rem;padding-right:.5rem;font-size:1.1rem}.navbar .quarto-navbar-tools div.dropdown{display:inline-block}.navbar .quarto-navbar-tools .quarto-navigation-tool{color:#545555}.navbar .quarto-navbar-tools .quarto-navigation-tool:hover{color:#1a5698}@media(max-width: 991.98px){.navbar .quarto-navbar-tools{margin-top:.25em;padding-top:.75em;display:block;color:solid #d4d4d4 1px;text-align:center;vertical-align:middle;margin-right:auto}}.navbar-nav .dropdown-menu{min-width:220px;font-size:.9rem}.navbar .navbar-nav .nav-link.dropdown-toggle::after{opacity:.75;vertical-align:.175em}.navbar ul.dropdown-menu{padding-top:0;padding-bottom:0}.navbar .dropdown-header{text-transform:uppercase;font-size:.8rem;padding:0 .5rem}.navbar .dropdown-item{padding:.4rem .5rem}.navbar .dropdown-item>i.bi{margin-left:.1rem;margin-right:.25em}.sidebar #quarto-search{margin-top:-1px}.sidebar #quarto-search svg.aa-SubmitIcon{width:16px;height:16px}.sidebar-navigation a{color:inherit}.sidebar-title{margin-top:.25rem;padding-bottom:.5rem;font-size:1.3rem;line-height:1.6rem;visibility:visible}.sidebar-title>a{font-size:inherit;text-decoration:none}.sidebar-title .sidebar-tools-main{margin-top:-6px}@media(max-width: 991.98px){#quarto-sidebar div.sidebar-header{padding-top:.2em}}.sidebar-header-stacked .sidebar-title{margin-top:.6rem}.sidebar-logo{max-width:90%;padding-bottom:.5rem}.sidebar-logo-link{text-decoration:none}.sidebar-navigation li a{text-decoration:none}.sidebar-navigation .quarto-navigation-tool{opacity:.7;font-size:.875rem}#quarto-sidebar>nav>.sidebar-tools-main{margin-left:14px}.sidebar-tools-main{display:inline-flex;margin-left:0px;order:2}.sidebar-tools-main:not(.tools-wide){vertical-align:middle}.sidebar-navigation .quarto-navigation-tool.dropdown-toggle::after{display:none}.sidebar.sidebar-navigation>*{padding-top:1em}.sidebar-item{margin-bottom:.2em}.sidebar-section{margin-top:.2em;padding-left:.5em;padding-bottom:.2em}.sidebar-item .sidebar-item-container{display:flex;justify-content:space-between}.sidebar-item-toggle:hover{cursor:pointer}.sidebar-item .sidebar-item-toggle .bi{font-size:.7rem;text-align:center}.sidebar-item .sidebar-item-toggle .bi-chevron-right::before{transition:transform 200ms ease}.sidebar-item .sidebar-item-toggle[aria-expanded=false] .bi-chevron-right::before{transform:none}.sidebar-item .sidebar-item-toggle[aria-expanded=true] .bi-chevron-right::before{transform:rotate(90deg)}.sidebar-navigation .sidebar-divider{margin-left:0;margin-right:0;margin-top:.5rem;margin-bottom:.5rem}@media(max-width: 991.98px){.quarto-secondary-nav{display:block}.quarto-secondary-nav button.quarto-search-button{padding-right:0em;padding-left:2em}.quarto-secondary-nav button.quarto-btn-toggle{margin-left:-0.75rem;margin-right:.15rem}.quarto-secondary-nav nav.quarto-page-breadcrumbs{display:flex;align-items:center;padding-right:1em;margin-left:-0.25em}.quarto-secondary-nav nav.quarto-page-breadcrumbs a{text-decoration:none}.quarto-secondary-nav nav.quarto-page-breadcrumbs ol.breadcrumb{margin-bottom:0}}@media(min-width: 992px){.quarto-secondary-nav{display:none}}.quarto-secondary-nav .quarto-btn-toggle{color:#595959}.quarto-secondary-nav[aria-expanded=false] .quarto-btn-toggle .bi-chevron-right::before{transform:none}.quarto-secondary-nav[aria-expanded=true] .quarto-btn-toggle .bi-chevron-right::before{transform:rotate(90deg)}.quarto-secondary-nav .quarto-btn-toggle .bi-chevron-right::before{transition:transform 200ms ease}.quarto-secondary-nav{cursor:pointer}.quarto-secondary-nav-title{margin-top:.3em;color:#595959;padding-top:4px}.quarto-secondary-nav nav.quarto-page-breadcrumbs{color:#595959}.quarto-secondary-nav nav.quarto-page-breadcrumbs a{color:#595959}.quarto-secondary-nav nav.quarto-page-breadcrumbs a:hover{color:rgba(27,88,157,.8)}.quarto-secondary-nav nav.quarto-page-breadcrumbs .breadcrumb-item::before{color:#8c8c8c}div.sidebar-item-container{color:#595959}div.sidebar-item-container:hover,div.sidebar-item-container:focus{color:rgba(27,88,157,.8)}div.sidebar-item-container.disabled{color:rgba(89,89,89,.75)}div.sidebar-item-container .active,div.sidebar-item-container .show>.nav-link,div.sidebar-item-container .sidebar-link>code{color:#1b589d}div.sidebar.sidebar-navigation.rollup.quarto-sidebar-toggle-contents,nav.sidebar.sidebar-navigation:not(.rollup){background-color:#fff}@media(max-width: 991.98px){.sidebar-navigation .sidebar-item a,.nav-page .nav-page-text,.sidebar-navigation{font-size:1rem}.sidebar-navigation ul.sidebar-section.depth1 .sidebar-section-item{font-size:1.1rem}.sidebar-logo{display:none}.sidebar.sidebar-navigation{position:static;border-bottom:1px solid #dee2e6}.sidebar.sidebar-navigation.collapsing{position:fixed;z-index:1000}.sidebar.sidebar-navigation.show{position:fixed;z-index:1000}.sidebar.sidebar-navigation{min-height:100%}nav.quarto-secondary-nav{background-color:#fff;border-bottom:1px solid #dee2e6}.sidebar .sidebar-footer{visibility:visible;padding-top:1rem;position:inherit}.sidebar-tools-collapse{display:block}}#quarto-sidebar{transition:width .15s ease-in}#quarto-sidebar>*{padding-right:1em}@media(max-width: 991.98px){#quarto-sidebar .sidebar-menu-container{white-space:nowrap;min-width:225px}#quarto-sidebar.show{transition:width .15s ease-out}}@media(min-width: 992px){#quarto-sidebar{display:flex;flex-direction:column}.nav-page .nav-page-text,.sidebar-navigation .sidebar-section .sidebar-item{font-size:.875rem}.sidebar-navigation .sidebar-item{font-size:.925rem}.sidebar.sidebar-navigation{display:block;position:sticky}.sidebar-search{width:100%}.sidebar .sidebar-footer{visibility:visible}}@media(max-width: 991.98px){#quarto-sidebar-glass{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(255,255,255,0);transition:background-color .15s ease-in;z-index:-1}#quarto-sidebar-glass.collapsing{z-index:1000}#quarto-sidebar-glass.show{transition:background-color .15s ease-out;background-color:rgba(102,102,102,.4);z-index:1000}}.sidebar .sidebar-footer{padding:.5rem 1rem;align-self:flex-end;color:#6c757d;width:100%}.quarto-page-breadcrumbs .breadcrumb-item+.breadcrumb-item,.quarto-page-breadcrumbs .breadcrumb-item{padding-right:.33em;padding-left:0}.quarto-page-breadcrumbs .breadcrumb-item::before{padding-right:.33em}.quarto-sidebar-footer{font-size:.875em}.sidebar-section .bi-chevron-right{vertical-align:middle}.sidebar-section .bi-chevron-right::before{font-size:.9em}.notransition{-webkit-transition:none !important;-moz-transition:none !important;-o-transition:none !important;transition:none !important}.btn:focus:not(:focus-visible){box-shadow:none}.page-navigation{display:flex;justify-content:space-between}.nav-page{padding-bottom:.75em}.nav-page .bi{font-size:1.8rem;vertical-align:middle}.nav-page .nav-page-text{padding-left:.25em;padding-right:.25em}.nav-page a{color:#6c757d;text-decoration:none;display:flex;align-items:center}.nav-page a:hover{color:#1f66b6}.toc-actions{display:flex}.toc-actions p{margin-block-start:0;margin-block-end:0}.toc-actions a{text-decoration:none;color:inherit;font-weight:400}.toc-actions a:hover{color:#1f66b6}.toc-actions .action-links{margin-left:4px}.sidebar nav[role=doc-toc] .toc-actions .bi{margin-left:-4px;font-size:.7rem;color:#6c757d}.sidebar nav[role=doc-toc] .toc-actions .bi:before{padding-top:3px}#quarto-margin-sidebar .toc-actions .bi:before{margin-top:.3rem;font-size:.7rem;color:#6c757d;vertical-align:top}.sidebar nav[role=doc-toc] .toc-actions>div:first-of-type{margin-top:-3px}#quarto-margin-sidebar .toc-actions p,.sidebar nav[role=doc-toc] .toc-actions p{font-size:.875rem}.nav-footer .toc-actions{padding-bottom:.5em;padding-top:.5em}.nav-footer .toc-actions :first-child{margin-left:auto}.nav-footer .toc-actions :last-child{margin-right:auto}.nav-footer .toc-actions .action-links{display:flex}.nav-footer .toc-actions .action-links p{padding-right:1.5em}.nav-footer .toc-actions .action-links p:last-of-type{padding-right:0}.nav-footer{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;align-items:baseline;text-align:center;padding-top:.5rem;padding-bottom:.5rem;background-color:#fff}body.nav-fixed{padding-top:64px}.nav-footer-contents{color:#6c757d;margin-top:.25rem}.nav-footer{min-height:3.5em;color:#757575}.nav-footer a{color:#757575}.nav-footer .nav-footer-left{font-size:.825em}.nav-footer .nav-footer-center{font-size:.825em}.nav-footer .nav-footer-right{font-size:.825em}.nav-footer-left .footer-items,.nav-footer-center .footer-items,.nav-footer-right .footer-items{display:inline-flex;padding-top:.3em;padding-bottom:.3em;margin-bottom:0em}.nav-footer-left .footer-items .nav-link,.nav-footer-center .footer-items .nav-link,.nav-footer-right .footer-items .nav-link{padding-left:.6em;padding-right:.6em}.nav-footer-left{flex:1 1 0px;text-align:left}.nav-footer-right{flex:1 1 0px;text-align:right}.nav-footer-center{flex:1 1 0px;min-height:3em;text-align:center}.nav-footer-center .footer-items{justify-content:center}@media(max-width: 767.98px){.nav-footer-center{margin-top:3em}}.navbar .quarto-reader-toggle.reader .quarto-reader-toggle-btn{background-color:#545555;border-radius:3px}.quarto-reader-toggle.reader.quarto-navigation-tool .quarto-reader-toggle-btn{background-color:#595959;border-radius:3px}.quarto-reader-toggle .quarto-reader-toggle-btn{display:inline-flex;padding-left:.2em;padding-right:.2em;margin-left:-0.2em;margin-right:-0.2em;text-align:center}.navbar .quarto-reader-toggle:not(.reader) .bi::before{background-image:url('data:image/svg+xml,')}.navbar .quarto-reader-toggle.reader .bi::before{background-image:url('data:image/svg+xml,')}.sidebar-navigation .quarto-reader-toggle:not(.reader) .bi::before{background-image:url('data:image/svg+xml,')}.sidebar-navigation .quarto-reader-toggle.reader .bi::before{background-image:url('data:image/svg+xml,')}#quarto-back-to-top{display:none;position:fixed;bottom:50px;background-color:#fff;border-radius:.25rem;box-shadow:0 .2rem .5rem #6c757d,0 0 .05rem #6c757d;color:#6c757d;text-decoration:none;font-size:.9em;text-align:center;left:50%;padding:.4rem .8rem;transform:translate(-50%, 0)}.aa-DetachedOverlay ul.aa-List,#quarto-search-results ul.aa-List{list-style:none;padding-left:0}.aa-DetachedOverlay .aa-Panel,#quarto-search-results .aa-Panel{background-color:#fff;position:absolute;z-index:2000}#quarto-search-results .aa-Panel{max-width:400px}#quarto-search input{font-size:.925rem}@media(min-width: 992px){.navbar #quarto-search{margin-left:.25rem;order:999}}@media(max-width: 991.98px){#quarto-sidebar .sidebar-search{display:none}}#quarto-sidebar .sidebar-search .aa-Autocomplete{width:100%}.navbar .aa-Autocomplete .aa-Form{width:180px}.navbar #quarto-search.type-overlay .aa-Autocomplete{width:40px}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form{background-color:inherit;border:none}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form:focus-within{box-shadow:none;outline:none}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form .aa-InputWrapper{display:none}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form .aa-InputWrapper:focus-within{display:inherit}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form .aa-Label svg,.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form .aa-LoadingIndicator svg{width:26px;height:26px;color:#545555;opacity:1}.navbar #quarto-search.type-overlay .aa-Autocomplete svg.aa-SubmitIcon{width:26px;height:26px;color:#545555;opacity:1}.aa-Autocomplete .aa-Form,.aa-DetachedFormContainer .aa-Form{align-items:center;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem;color:#373a3c;display:flex;line-height:1em;margin:0;position:relative;width:100%}.aa-Autocomplete .aa-Form:focus-within,.aa-DetachedFormContainer .aa-Form:focus-within{box-shadow:rgba(39,128,227,.6) 0 0 0 1px;outline:currentColor none medium}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix{align-items:center;display:flex;flex-shrink:0;order:1}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-Label,.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-Label,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator{cursor:initial;flex-shrink:0;padding:0;text-align:left}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-Label svg,.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator svg,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-Label svg,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator svg{color:#373a3c;opacity:.5}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-SubmitButton,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-SubmitButton{appearance:none;background:none;border:0;margin:0}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator{align-items:center;display:flex;justify-content:center}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator[hidden],.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator[hidden]{display:none}.aa-Autocomplete .aa-Form .aa-InputWrapper,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper{order:3;position:relative;width:100%}.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input{appearance:none;background:none;border:0;color:#373a3c;font:inherit;height:calc(1.5em + .1rem + 2px);padding:0;width:100%}.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::placeholder,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::placeholder{color:#373a3c;opacity:.8}.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input:focus,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input:focus{border-color:none;box-shadow:none;outline:none}.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-decoration,.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-cancel-button,.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-results-button,.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-results-decoration,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-decoration,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-cancel-button,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-results-button,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-results-decoration{display:none}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix{align-items:center;display:flex;order:4}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton{align-items:center;background:none;border:0;color:#373a3c;opacity:.8;cursor:pointer;display:flex;margin:0;width:calc(1.5em + .1rem + 2px)}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton:hover,.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton:focus,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton:hover,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton:focus{color:#373a3c;opacity:.8}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton[hidden],.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton[hidden]{display:none}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton svg,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton svg{width:calc(1.5em + 0.75rem + 2px)}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-CopyButton,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-CopyButton{border:none;align-items:center;background:none;color:#373a3c;opacity:.4;font-size:.7rem;cursor:pointer;display:none;margin:0;width:calc(1em + .1rem + 2px)}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-CopyButton:hover,.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-CopyButton:focus,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-CopyButton:hover,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-CopyButton:focus{color:#373a3c;opacity:.8}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-CopyButton[hidden],.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-CopyButton[hidden]{display:none}.aa-PanelLayout:empty{display:none}.quarto-search-no-results.no-query{display:none}.aa-Source:has(.no-query){display:none}#quarto-search-results .aa-Panel{border:solid #ced4da 1px}#quarto-search-results .aa-SourceNoResults{width:398px}.aa-DetachedOverlay .aa-Panel,#quarto-search-results .aa-Panel{max-height:65vh;overflow-y:auto;font-size:.925rem}.aa-DetachedOverlay .aa-SourceNoResults,#quarto-search-results .aa-SourceNoResults{height:60px;display:flex;justify-content:center;align-items:center}.aa-DetachedOverlay .search-error,#quarto-search-results .search-error{padding-top:10px;padding-left:20px;padding-right:20px;cursor:default}.aa-DetachedOverlay .search-error .search-error-title,#quarto-search-results .search-error .search-error-title{font-size:1.1rem;margin-bottom:.5rem}.aa-DetachedOverlay .search-error .search-error-title .search-error-icon,#quarto-search-results .search-error .search-error-title .search-error-icon{margin-right:8px}.aa-DetachedOverlay .search-error .search-error-text,#quarto-search-results .search-error .search-error-text{font-weight:300}.aa-DetachedOverlay .search-result-text,#quarto-search-results .search-result-text{font-weight:300;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;line-height:1.2rem;max-height:2.4rem}.aa-DetachedOverlay .aa-SourceHeader .search-result-header,#quarto-search-results .aa-SourceHeader .search-result-header{font-size:.875rem;background-color:#f2f2f2;padding-left:14px;padding-bottom:4px;padding-top:4px}.aa-DetachedOverlay .aa-SourceHeader .search-result-header-no-results,#quarto-search-results .aa-SourceHeader .search-result-header-no-results{display:none}.aa-DetachedOverlay .aa-SourceFooter .algolia-search-logo,#quarto-search-results .aa-SourceFooter .algolia-search-logo{width:110px;opacity:.85;margin:8px;float:right}.aa-DetachedOverlay .search-result-section,#quarto-search-results .search-result-section{font-size:.925em}.aa-DetachedOverlay a.search-result-link,#quarto-search-results a.search-result-link{color:inherit;text-decoration:none}.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item,#quarto-search-results li.aa-Item[aria-selected=true] .search-item{background-color:#2780e3}.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item.search-result-more,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-result-section,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-result-text,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-result-title-container,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-result-text-container,#quarto-search-results li.aa-Item[aria-selected=true] .search-item.search-result-more,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-result-section,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-result-text,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-result-title-container,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-result-text-container{color:#fff;background-color:#2780e3}.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item mark.search-match,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-match.mark,#quarto-search-results li.aa-Item[aria-selected=true] .search-item mark.search-match,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-match.mark{color:#fff;background-color:#4b95e8}.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item,#quarto-search-results li.aa-Item[aria-selected=false] .search-item{background-color:#fff}.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item.search-result-more,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-result-section,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-result-text,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-result-title-container,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-result-text-container,#quarto-search-results li.aa-Item[aria-selected=false] .search-item.search-result-more,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-result-section,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-result-text,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-result-title-container,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-result-text-container{color:#373a3c}.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item mark.search-match,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-match.mark,#quarto-search-results li.aa-Item[aria-selected=false] .search-item mark.search-match,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-match.mark{color:inherit;background-color:#e5effc}.aa-DetachedOverlay .aa-Item .search-result-doc:not(.document-selectable) .search-result-title-container,#quarto-search-results .aa-Item .search-result-doc:not(.document-selectable) .search-result-title-container{background-color:#fff;color:#373a3c}.aa-DetachedOverlay .aa-Item .search-result-doc:not(.document-selectable) .search-result-text-container,#quarto-search-results .aa-Item .search-result-doc:not(.document-selectable) .search-result-text-container{padding-top:0px}.aa-DetachedOverlay li.aa-Item .search-result-doc.document-selectable .search-result-text-container,#quarto-search-results li.aa-Item .search-result-doc.document-selectable .search-result-text-container{margin-top:-4px}.aa-DetachedOverlay .aa-Item,#quarto-search-results .aa-Item{cursor:pointer}.aa-DetachedOverlay .aa-Item .search-item,#quarto-search-results .aa-Item .search-item{border-left:none;border-right:none;border-top:none;background-color:#fff;border-color:#ced4da;color:#373a3c}.aa-DetachedOverlay .aa-Item .search-item p,#quarto-search-results .aa-Item .search-item p{margin-top:0;margin-bottom:0}.aa-DetachedOverlay .aa-Item .search-item i.bi,#quarto-search-results .aa-Item .search-item i.bi{padding-left:8px;padding-right:8px;font-size:1.3em}.aa-DetachedOverlay .aa-Item .search-item .search-result-title,#quarto-search-results .aa-Item .search-item .search-result-title{margin-top:.3em;margin-bottom:.1rem}.aa-DetachedOverlay .aa-Item .search-result-title-container,#quarto-search-results .aa-Item .search-result-title-container{font-size:1em;display:flex;padding:6px 4px 6px 4px}.aa-DetachedOverlay .aa-Item .search-result-text-container,#quarto-search-results .aa-Item .search-result-text-container{padding-bottom:8px;padding-right:8px;margin-left:44px}.aa-DetachedOverlay .aa-Item .search-result-doc-section,.aa-DetachedOverlay .aa-Item .search-result-more,#quarto-search-results .aa-Item .search-result-doc-section,#quarto-search-results .aa-Item .search-result-more{padding-top:8px;padding-bottom:8px;padding-left:44px}.aa-DetachedOverlay .aa-Item .search-result-more,#quarto-search-results .aa-Item .search-result-more{font-size:.8em;font-weight:400}.aa-DetachedOverlay .aa-Item .search-result-doc,#quarto-search-results .aa-Item .search-result-doc{border-top:1px solid #ced4da}.aa-DetachedSearchButton{background:none;border:none}.aa-DetachedSearchButton .aa-DetachedSearchButtonPlaceholder{display:none}.navbar .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon{color:#545555}.sidebar-tools-collapse #quarto-search,.sidebar-tools-main #quarto-search{display:inline}.sidebar-tools-collapse #quarto-search .aa-Autocomplete,.sidebar-tools-main #quarto-search .aa-Autocomplete{display:inline}.sidebar-tools-collapse #quarto-search .aa-DetachedSearchButton,.sidebar-tools-main #quarto-search .aa-DetachedSearchButton{padding-left:4px;padding-right:4px}.sidebar-tools-collapse #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon,.sidebar-tools-main #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon{color:#595959}.sidebar-tools-collapse #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon .aa-SubmitIcon,.sidebar-tools-main #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon .aa-SubmitIcon{margin-top:-3px}.aa-DetachedContainer{background:rgba(255,255,255,.65);width:90%;bottom:0;box-shadow:rgba(206,212,218,.6) 0 0 0 1px;outline:currentColor none medium;display:flex;flex-direction:column;left:0;margin:0;overflow:hidden;padding:0;position:fixed;right:0;top:0;z-index:1101}.aa-DetachedContainer::after{height:32px}.aa-DetachedContainer .aa-SourceHeader{margin:var(--aa-spacing-half) 0 var(--aa-spacing-half) 2px}.aa-DetachedContainer .aa-Panel{background-color:#fff;border-radius:0;box-shadow:none;flex-grow:1;margin:0;padding:0;position:relative}.aa-DetachedContainer .aa-PanelLayout{bottom:0;box-shadow:none;left:0;margin:0;max-height:none;overflow-y:auto;position:absolute;right:0;top:0;width:100%}.aa-DetachedFormContainer{background-color:#fff;border-bottom:1px solid #ced4da;display:flex;flex-direction:row;justify-content:space-between;margin:0;padding:.5em}.aa-DetachedCancelButton{background:none;font-size:.8em;border:0;border-radius:3px;color:#373a3c;cursor:pointer;margin:0 0 0 .5em;padding:0 .5em}.aa-DetachedCancelButton:hover,.aa-DetachedCancelButton:focus{box-shadow:rgba(39,128,227,.6) 0 0 0 1px;outline:currentColor none medium}.aa-DetachedContainer--modal{bottom:inherit;height:auto;margin:0 auto;position:absolute;top:100px;border-radius:6px;max-width:850px}@media(max-width: 575.98px){.aa-DetachedContainer--modal{width:100%;top:0px;border-radius:0px;border:none}}.aa-DetachedContainer--modal .aa-PanelLayout{max-height:var(--aa-detached-modal-max-height);padding-bottom:var(--aa-spacing-half);position:static}.aa-Detached{height:100vh;overflow:hidden}.aa-DetachedOverlay{background-color:rgba(55,58,60,.4);position:fixed;left:0;right:0;top:0;margin:0;padding:0;height:100vh;z-index:1100}.quarto-listing{padding-bottom:1em}.listing-pagination{padding-top:.5em}ul.pagination{float:right;padding-left:8px;padding-top:.5em}ul.pagination li{padding-right:.75em}ul.pagination li.disabled a,ul.pagination li.active a{color:#373a3c;text-decoration:none}ul.pagination li:last-of-type{padding-right:0}.listing-actions-group{display:flex}.quarto-listing-filter{margin-bottom:1em;width:200px;margin-left:auto}.quarto-listing-sort{margin-bottom:1em;margin-right:auto;width:auto}.quarto-listing-sort .input-group-text{font-size:.8em}.input-group-text{border-right:none}.quarto-listing-sort select.form-select{font-size:.8em}.listing-no-matching{text-align:center;padding-top:2em;padding-bottom:3em;font-size:1em}#quarto-margin-sidebar .quarto-listing-category{padding-top:0;font-size:1rem}#quarto-margin-sidebar .quarto-listing-category-title{cursor:pointer;font-weight:600;font-size:1rem}.quarto-listing-category .category{cursor:pointer}.quarto-listing-category .category.active{font-weight:600}.quarto-listing-category.category-cloud{display:flex;flex-wrap:wrap;align-items:baseline}.quarto-listing-category.category-cloud .category{padding-right:5px}.quarto-listing-category.category-cloud .category-cloud-1{font-size:.75em}.quarto-listing-category.category-cloud .category-cloud-2{font-size:.95em}.quarto-listing-category.category-cloud .category-cloud-3{font-size:1.15em}.quarto-listing-category.category-cloud .category-cloud-4{font-size:1.35em}.quarto-listing-category.category-cloud .category-cloud-5{font-size:1.55em}.quarto-listing-category.category-cloud .category-cloud-6{font-size:1.75em}.quarto-listing-category.category-cloud .category-cloud-7{font-size:1.95em}.quarto-listing-category.category-cloud .category-cloud-8{font-size:2.15em}.quarto-listing-category.category-cloud .category-cloud-9{font-size:2.35em}.quarto-listing-category.category-cloud .category-cloud-10{font-size:2.55em}.quarto-listing-cols-1{grid-template-columns:repeat(1, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-1{grid-template-columns:repeat(1, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-1{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-2{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-2{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-2{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-3{grid-template-columns:repeat(3, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-3{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-3{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-4{grid-template-columns:repeat(4, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-4{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-4{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-5{grid-template-columns:repeat(5, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-5{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-5{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-6{grid-template-columns:repeat(6, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-6{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-6{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-7{grid-template-columns:repeat(7, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-7{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-7{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-8{grid-template-columns:repeat(8, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-8{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-8{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-9{grid-template-columns:repeat(9, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-9{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-9{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-10{grid-template-columns:repeat(10, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-10{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-10{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-11{grid-template-columns:repeat(11, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-11{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-11{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-12{grid-template-columns:repeat(12, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-12{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-12{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-grid{gap:1.5em}.quarto-grid-item.borderless{border:none}.quarto-grid-item.borderless .listing-categories .listing-category:last-of-type,.quarto-grid-item.borderless .listing-categories .listing-category:first-of-type{padding-left:0}.quarto-grid-item.borderless .listing-categories .listing-category{border:0}.quarto-grid-link{text-decoration:none;color:inherit}.quarto-grid-link:hover{text-decoration:none;color:inherit}.quarto-grid-item h5.title,.quarto-grid-item .title.h5{margin-top:0;margin-bottom:0}.quarto-grid-item .card-footer{display:flex;justify-content:space-between;font-size:.8em}.quarto-grid-item .card-footer p{margin-bottom:0}.quarto-grid-item p.card-img-top{margin-bottom:0}.quarto-grid-item p.card-img-top>img{object-fit:cover}.quarto-grid-item .card-other-values{margin-top:.5em;font-size:.8em}.quarto-grid-item .card-other-values tr{margin-bottom:.5em}.quarto-grid-item .card-other-values tr>td:first-of-type{font-weight:600;padding-right:1em;padding-left:1em;vertical-align:top}.quarto-grid-item div.post-contents{display:flex;flex-direction:column;text-decoration:none;height:100%}.quarto-grid-item .listing-item-img-placeholder{background-color:#adb5bd;flex-shrink:0}.quarto-grid-item .card-attribution{padding-top:1em;display:flex;gap:1em;text-transform:uppercase;color:#6c757d;font-weight:500;flex-grow:10;align-items:flex-end}.quarto-grid-item .description{padding-bottom:1em}.quarto-grid-item .card-attribution .date{align-self:flex-end}.quarto-grid-item .card-attribution.justify{justify-content:space-between}.quarto-grid-item .card-attribution.start{justify-content:flex-start}.quarto-grid-item .card-attribution.end{justify-content:flex-end}.quarto-grid-item .card-title{margin-bottom:.1em}.quarto-grid-item .card-subtitle{padding-top:.25em}.quarto-grid-item .card-text{font-size:.9em}.quarto-grid-item .listing-reading-time{padding-bottom:.25em}.quarto-grid-item .card-text-small{font-size:.8em}.quarto-grid-item .card-subtitle.subtitle{font-size:.9em;font-weight:600;padding-bottom:.5em}.quarto-grid-item .listing-categories{display:flex;flex-wrap:wrap;padding-bottom:5px}.quarto-grid-item .listing-categories .listing-category{color:#6c757d;border:solid 1px #dee2e6;border-radius:.25rem;text-transform:uppercase;font-size:.65em;padding-left:.5em;padding-right:.5em;padding-top:.15em;padding-bottom:.15em;cursor:pointer;margin-right:4px;margin-bottom:4px}.quarto-grid-item.card-right{text-align:right}.quarto-grid-item.card-right .listing-categories{justify-content:flex-end}.quarto-grid-item.card-left{text-align:left}.quarto-grid-item.card-center{text-align:center}.quarto-grid-item.card-center .listing-description{text-align:justify}.quarto-grid-item.card-center .listing-categories{justify-content:center}table.quarto-listing-table td.image{padding:0px}table.quarto-listing-table td.image img{width:100%;max-width:50px;object-fit:contain}table.quarto-listing-table a{text-decoration:none}table.quarto-listing-table th a{color:inherit}table.quarto-listing-table th a.asc:after{margin-bottom:-2px;margin-left:5px;display:inline-block;height:1rem;width:1rem;background-repeat:no-repeat;background-size:1rem 1rem;background-image:url('data:image/svg+xml,');content:""}table.quarto-listing-table th a.desc:after{margin-bottom:-2px;margin-left:5px;display:inline-block;height:1rem;width:1rem;background-repeat:no-repeat;background-size:1rem 1rem;background-image:url('data:image/svg+xml,');content:""}table.quarto-listing-table.table-hover td{cursor:pointer}.quarto-post.image-left{flex-direction:row}.quarto-post.image-right{flex-direction:row-reverse}@media(max-width: 767.98px){.quarto-post.image-right,.quarto-post.image-left{gap:0em;flex-direction:column}.quarto-post .metadata{padding-bottom:1em;order:2}.quarto-post .body{order:1}.quarto-post .thumbnail{order:3}}.list.quarto-listing-default div:last-of-type{border-bottom:none}@media(min-width: 992px){.quarto-listing-container-default{margin-right:2em}}div.quarto-post{display:flex;gap:2em;margin-bottom:1.5em;border-bottom:1px solid #dee2e6}@media(max-width: 767.98px){div.quarto-post{padding-bottom:1em}}div.quarto-post .metadata{flex-basis:20%;flex-grow:0;margin-top:.2em;flex-shrink:10}div.quarto-post .thumbnail{flex-basis:30%;flex-grow:0;flex-shrink:0}div.quarto-post .thumbnail img{margin-top:.4em;width:100%;object-fit:cover}div.quarto-post .body{flex-basis:45%;flex-grow:1;flex-shrink:0}div.quarto-post .body h3.listing-title,div.quarto-post .body .listing-title.h3{margin-top:0px;margin-bottom:0px;border-bottom:none}div.quarto-post .body .listing-subtitle{font-size:.875em;margin-bottom:.5em;margin-top:.2em}div.quarto-post .body .description{font-size:.9em}div.quarto-post a{color:#373a3c;display:flex;flex-direction:column;text-decoration:none}div.quarto-post a div.description{flex-shrink:0}div.quarto-post .metadata{display:flex;flex-direction:column;font-size:.8em;font-family:var(--bs-font-sans-serif);flex-basis:33%}div.quarto-post .listing-categories{display:flex;flex-wrap:wrap;padding-bottom:5px}div.quarto-post .listing-categories .listing-category{color:#6c757d;border:solid 1px #dee2e6;border-radius:.25rem;text-transform:uppercase;font-size:.65em;padding-left:.5em;padding-right:.5em;padding-top:.15em;padding-bottom:.15em;cursor:pointer;margin-right:4px;margin-bottom:4px}div.quarto-post .listing-description{margin-bottom:.5em}div.quarto-about-jolla{display:flex !important;flex-direction:column;align-items:center;margin-top:10%;padding-bottom:1em}div.quarto-about-jolla .about-image{object-fit:cover;margin-left:auto;margin-right:auto;margin-bottom:1.5em}div.quarto-about-jolla img.round{border-radius:50%}div.quarto-about-jolla img.rounded{border-radius:10px}div.quarto-about-jolla .quarto-title h1.title,div.quarto-about-jolla .quarto-title .title.h1{text-align:center}div.quarto-about-jolla .quarto-title .description{text-align:center}div.quarto-about-jolla h2,div.quarto-about-jolla .h2{border-bottom:none}div.quarto-about-jolla .about-sep{width:60%}div.quarto-about-jolla main{text-align:center}div.quarto-about-jolla .about-links{display:flex}@media(min-width: 992px){div.quarto-about-jolla .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-jolla .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-jolla .about-link{color:#686d71;text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-jolla .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-jolla .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-jolla .about-link:hover{color:#2780e3}div.quarto-about-jolla .about-link i.bi{margin-right:.15em}div.quarto-about-solana{display:flex !important;flex-direction:column;padding-top:3em !important;padding-bottom:1em}div.quarto-about-solana .about-entity{display:flex !important;align-items:start;justify-content:space-between}@media(min-width: 992px){div.quarto-about-solana .about-entity{flex-direction:row}}@media(max-width: 991.98px){div.quarto-about-solana .about-entity{flex-direction:column-reverse;align-items:center;text-align:center}}div.quarto-about-solana .about-entity .entity-contents{display:flex;flex-direction:column}@media(max-width: 767.98px){div.quarto-about-solana .about-entity .entity-contents{width:100%}}div.quarto-about-solana .about-entity .about-image{object-fit:cover}@media(max-width: 991.98px){div.quarto-about-solana .about-entity .about-image{margin-bottom:1.5em}}div.quarto-about-solana .about-entity img.round{border-radius:50%}div.quarto-about-solana .about-entity img.rounded{border-radius:10px}div.quarto-about-solana .about-entity .about-links{display:flex;justify-content:left;padding-bottom:1.2em}@media(min-width: 992px){div.quarto-about-solana .about-entity .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-solana .about-entity .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-solana .about-entity .about-link{color:#686d71;text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-solana .about-entity .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-solana .about-entity .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-solana .about-entity .about-link:hover{color:#2780e3}div.quarto-about-solana .about-entity .about-link i.bi{margin-right:.15em}div.quarto-about-solana .about-contents{padding-right:1.5em;flex-basis:0;flex-grow:1}div.quarto-about-solana .about-contents main.content{margin-top:0}div.quarto-about-solana .about-contents h2,div.quarto-about-solana .about-contents .h2{border-bottom:none}div.quarto-about-trestles{display:flex !important;flex-direction:row;padding-top:3em !important;padding-bottom:1em}@media(max-width: 991.98px){div.quarto-about-trestles{flex-direction:column;padding-top:0em !important}}div.quarto-about-trestles .about-entity{display:flex !important;flex-direction:column;align-items:center;text-align:center;padding-right:1em}@media(min-width: 992px){div.quarto-about-trestles .about-entity{flex:0 0 42%}}div.quarto-about-trestles .about-entity .about-image{object-fit:cover;margin-bottom:1.5em}div.quarto-about-trestles .about-entity img.round{border-radius:50%}div.quarto-about-trestles .about-entity img.rounded{border-radius:10px}div.quarto-about-trestles .about-entity .about-links{display:flex;justify-content:center}@media(min-width: 992px){div.quarto-about-trestles .about-entity .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-trestles .about-entity .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-trestles .about-entity .about-link{color:#686d71;text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-trestles .about-entity .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-trestles .about-entity .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-trestles .about-entity .about-link:hover{color:#2780e3}div.quarto-about-trestles .about-entity .about-link i.bi{margin-right:.15em}div.quarto-about-trestles .about-contents{flex-basis:0;flex-grow:1}div.quarto-about-trestles .about-contents h2,div.quarto-about-trestles .about-contents .h2{border-bottom:none}@media(min-width: 992px){div.quarto-about-trestles .about-contents{border-left:solid 1px #dee2e6;padding-left:1.5em}}div.quarto-about-trestles .about-contents main.content{margin-top:0}div.quarto-about-marquee{padding-bottom:1em}div.quarto-about-marquee .about-contents{display:flex;flex-direction:column}div.quarto-about-marquee .about-image{max-height:550px;margin-bottom:1.5em;object-fit:cover}div.quarto-about-marquee img.round{border-radius:50%}div.quarto-about-marquee img.rounded{border-radius:10px}div.quarto-about-marquee h2,div.quarto-about-marquee .h2{border-bottom:none}div.quarto-about-marquee .about-links{display:flex;justify-content:center;padding-top:1.5em}@media(min-width: 992px){div.quarto-about-marquee .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-marquee .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-marquee .about-link{color:#686d71;text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-marquee .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-marquee .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-marquee .about-link:hover{color:#2780e3}div.quarto-about-marquee .about-link i.bi{margin-right:.15em}@media(min-width: 992px){div.quarto-about-marquee .about-link{border:none}}div.quarto-about-broadside{display:flex;flex-direction:column;padding-bottom:1em}div.quarto-about-broadside .about-main{display:flex !important;padding-top:0 !important}@media(min-width: 992px){div.quarto-about-broadside .about-main{flex-direction:row;align-items:flex-start}}@media(max-width: 991.98px){div.quarto-about-broadside .about-main{flex-direction:column}}@media(max-width: 991.98px){div.quarto-about-broadside .about-main .about-entity{flex-shrink:0;width:100%;height:450px;margin-bottom:1.5em;background-size:cover;background-repeat:no-repeat}}@media(min-width: 992px){div.quarto-about-broadside .about-main .about-entity{flex:0 10 50%;margin-right:1.5em;width:100%;height:100%;background-size:100%;background-repeat:no-repeat}}div.quarto-about-broadside .about-main .about-contents{padding-top:14px;flex:0 0 50%}div.quarto-about-broadside h2,div.quarto-about-broadside .h2{border-bottom:none}div.quarto-about-broadside .about-sep{margin-top:1.5em;width:60%;align-self:center}div.quarto-about-broadside .about-links{display:flex;justify-content:center;column-gap:20px;padding-top:1.5em}@media(min-width: 992px){div.quarto-about-broadside .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-broadside .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-broadside .about-link{color:#686d71;text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-broadside .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-broadside .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-broadside .about-link:hover{color:#2780e3}div.quarto-about-broadside .about-link i.bi{margin-right:.15em}@media(min-width: 992px){div.quarto-about-broadside .about-link{border:none}}.tippy-box[data-theme~=quarto]{background-color:#fff;border:solid 1px #dee2e6;border-radius:.25rem;color:#373a3c;font-size:.875rem}.tippy-box[data-theme~=quarto]>.tippy-backdrop{background-color:#fff}.tippy-box[data-theme~=quarto]>.tippy-arrow:after,.tippy-box[data-theme~=quarto]>.tippy-svg-arrow:after{content:"";position:absolute;z-index:-1}.tippy-box[data-theme~=quarto]>.tippy-arrow:after{border-color:rgba(0,0,0,0);border-style:solid}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-6px}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-6px}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-6px}.tippy-box[data-placement^=left]>.tippy-arrow:before{right:-6px}.tippy-box[data-theme~=quarto][data-placement^=top]>.tippy-arrow:before{border-top-color:#fff}.tippy-box[data-theme~=quarto][data-placement^=top]>.tippy-arrow:after{border-top-color:#dee2e6;border-width:7px 7px 0;top:17px;left:1px}.tippy-box[data-theme~=quarto][data-placement^=top]>.tippy-svg-arrow>svg{top:16px}.tippy-box[data-theme~=quarto][data-placement^=top]>.tippy-svg-arrow:after{top:17px}.tippy-box[data-theme~=quarto][data-placement^=bottom]>.tippy-arrow:before{border-bottom-color:#fff;bottom:16px}.tippy-box[data-theme~=quarto][data-placement^=bottom]>.tippy-arrow:after{border-bottom-color:#dee2e6;border-width:0 7px 7px;bottom:17px;left:1px}.tippy-box[data-theme~=quarto][data-placement^=bottom]>.tippy-svg-arrow>svg{bottom:15px}.tippy-box[data-theme~=quarto][data-placement^=bottom]>.tippy-svg-arrow:after{bottom:17px}.tippy-box[data-theme~=quarto][data-placement^=left]>.tippy-arrow:before{border-left-color:#fff}.tippy-box[data-theme~=quarto][data-placement^=left]>.tippy-arrow:after{border-left-color:#dee2e6;border-width:7px 0 7px 7px;left:17px;top:1px}.tippy-box[data-theme~=quarto][data-placement^=left]>.tippy-svg-arrow>svg{left:11px}.tippy-box[data-theme~=quarto][data-placement^=left]>.tippy-svg-arrow:after{left:12px}.tippy-box[data-theme~=quarto][data-placement^=right]>.tippy-arrow:before{border-right-color:#fff;right:16px}.tippy-box[data-theme~=quarto][data-placement^=right]>.tippy-arrow:after{border-width:7px 7px 7px 0;right:17px;top:1px;border-right-color:#dee2e6}.tippy-box[data-theme~=quarto][data-placement^=right]>.tippy-svg-arrow>svg{right:11px}.tippy-box[data-theme~=quarto][data-placement^=right]>.tippy-svg-arrow:after{right:12px}.tippy-box[data-theme~=quarto]>.tippy-svg-arrow{fill:#373a3c}.tippy-box[data-theme~=quarto]>.tippy-svg-arrow:after{background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMCA2czEuNzk2LS4wMTMgNC42Ny0zLjYxNUM1Ljg1MS45IDYuOTMuMDA2IDggMGMxLjA3LS4wMDYgMi4xNDguODg3IDMuMzQzIDIuMzg1QzE0LjIzMyA2LjAwNSAxNiA2IDE2IDZIMHoiIGZpbGw9InJnYmEoMCwgOCwgMTYsIDAuMikiLz48L3N2Zz4=);background-size:16px 6px;width:16px;height:6px}.top-right{position:absolute;top:1em;right:1em}.hidden{display:none !important}.zindex-bottom{z-index:-1 !important}.quarto-layout-panel{margin-bottom:1em}.quarto-layout-panel>figure{width:100%}.quarto-layout-panel>figure>figcaption,.quarto-layout-panel>.panel-caption{margin-top:10pt}.quarto-layout-panel>.table-caption{margin-top:0px}.table-caption p{margin-bottom:.5em}.quarto-layout-row{display:flex;flex-direction:row;align-items:flex-start}.quarto-layout-valign-top{align-items:flex-start}.quarto-layout-valign-bottom{align-items:flex-end}.quarto-layout-valign-center{align-items:center}.quarto-layout-cell{position:relative;margin-right:20px}.quarto-layout-cell:last-child{margin-right:0}.quarto-layout-cell figure,.quarto-layout-cell>p{margin:.2em}.quarto-layout-cell img{max-width:100%}.quarto-layout-cell .html-widget{width:100% !important}.quarto-layout-cell div figure p{margin:0}.quarto-layout-cell figure{display:inline-block;margin-inline-start:0;margin-inline-end:0}.quarto-layout-cell table{display:inline-table}.quarto-layout-cell-subref figcaption,figure .quarto-layout-row figure figcaption{text-align:center;font-style:italic}.quarto-figure{position:relative;margin-bottom:1em}.quarto-figure>figure{width:100%;margin-bottom:0}.quarto-figure-left>figure>p,.quarto-figure-left>figure>div{text-align:left}.quarto-figure-center>figure>p,.quarto-figure-center>figure>div{text-align:center}.quarto-figure-right>figure>p,.quarto-figure-right>figure>div{text-align:right}figure>p:empty{display:none}figure>p:first-child{margin-top:0;margin-bottom:0}figure>figcaption{margin-top:.5em}div[id^=tbl-]{position:relative}.quarto-figure>.anchorjs-link{position:absolute;top:.6em;right:.5em}div[id^=tbl-]>.anchorjs-link{position:absolute;top:.7em;right:.3em}.quarto-figure:hover>.anchorjs-link,div[id^=tbl-]:hover>.anchorjs-link,h2:hover>.anchorjs-link,.h2:hover>.anchorjs-link,h3:hover>.anchorjs-link,.h3:hover>.anchorjs-link,h4:hover>.anchorjs-link,.h4:hover>.anchorjs-link,h5:hover>.anchorjs-link,.h5:hover>.anchorjs-link,h6:hover>.anchorjs-link,.h6:hover>.anchorjs-link,.reveal-anchorjs-link>.anchorjs-link{opacity:1}#title-block-header{margin-block-end:1rem;position:relative;margin-top:-1px}#title-block-header .abstract{margin-block-start:1rem}#title-block-header .abstract .abstract-title{font-weight:600}#title-block-header a{text-decoration:none}#title-block-header .author,#title-block-header .date,#title-block-header .doi{margin-block-end:.2rem}#title-block-header .quarto-title-block>div{display:flex}#title-block-header .quarto-title-block>div>h1,#title-block-header .quarto-title-block>div>.h1{flex-grow:1}#title-block-header .quarto-title-block>div>button{flex-shrink:0;height:2.25rem;margin-top:0}@media(min-width: 992px){#title-block-header .quarto-title-block>div>button{margin-top:5px}}tr.header>th>p:last-of-type{margin-bottom:0px}table,.table{caption-side:top;margin-bottom:1.5rem}caption,.table-caption{padding-top:.5rem;padding-bottom:.5rem;text-align:center}.utterances{max-width:none;margin-left:-8px}iframe{margin-bottom:1em}details{margin-bottom:1em}details[show]{margin-bottom:0}details>summary{color:#6c757d}details>summary>p:only-child{display:inline}pre.sourceCode,code.sourceCode{position:relative}p code:not(.sourceCode){white-space:pre-wrap}code{white-space:pre}@media print{code{white-space:pre-wrap}}pre>code{display:block}pre>code.sourceCode{white-space:pre}pre>code.sourceCode>span>a:first-child::before{text-decoration:none}pre.code-overflow-wrap>code.sourceCode{white-space:pre-wrap}pre.code-overflow-scroll>code.sourceCode{white-space:pre}code a:any-link{color:inherit;text-decoration:none}code a:hover{color:inherit;text-decoration:underline}ul.task-list{padding-left:1em}[data-tippy-root]{display:inline-block}.tippy-content .footnote-back{display:none}.quarto-embedded-source-code{display:none}.quarto-unresolved-ref{font-weight:600}.quarto-cover-image{max-width:35%;float:right;margin-left:30px}.cell-output-display .widget-subarea{margin-bottom:1em}.cell-output-display:not(.no-overflow-x),.knitsql-table:not(.no-overflow-x){overflow-x:auto}.panel-input{margin-bottom:1em}.panel-input>div,.panel-input>div>div{display:inline-block;vertical-align:top;padding-right:12px}.panel-input>p:last-child{margin-bottom:0}.layout-sidebar{margin-bottom:1em}.layout-sidebar .tab-content{border:none}.tab-content>.page-columns.active{display:grid}div.sourceCode>iframe{width:100%;height:300px;margin-bottom:-0.5em}div.ansi-escaped-output{font-family:monospace;display:block}/*! +* +* ansi colors from IPython notebook's +* +*/.ansi-black-fg{color:#3e424d}.ansi-black-bg{background-color:#3e424d}.ansi-black-intense-fg{color:#282c36}.ansi-black-intense-bg{background-color:#282c36}.ansi-red-fg{color:#e75c58}.ansi-red-bg{background-color:#e75c58}.ansi-red-intense-fg{color:#b22b31}.ansi-red-intense-bg{background-color:#b22b31}.ansi-green-fg{color:#00a250}.ansi-green-bg{background-color:#00a250}.ansi-green-intense-fg{color:#007427}.ansi-green-intense-bg{background-color:#007427}.ansi-yellow-fg{color:#ddb62b}.ansi-yellow-bg{background-color:#ddb62b}.ansi-yellow-intense-fg{color:#b27d12}.ansi-yellow-intense-bg{background-color:#b27d12}.ansi-blue-fg{color:#208ffb}.ansi-blue-bg{background-color:#208ffb}.ansi-blue-intense-fg{color:#0065ca}.ansi-blue-intense-bg{background-color:#0065ca}.ansi-magenta-fg{color:#d160c4}.ansi-magenta-bg{background-color:#d160c4}.ansi-magenta-intense-fg{color:#a03196}.ansi-magenta-intense-bg{background-color:#a03196}.ansi-cyan-fg{color:#60c6c8}.ansi-cyan-bg{background-color:#60c6c8}.ansi-cyan-intense-fg{color:#258f8f}.ansi-cyan-intense-bg{background-color:#258f8f}.ansi-white-fg{color:#c5c1b4}.ansi-white-bg{background-color:#c5c1b4}.ansi-white-intense-fg{color:#a1a6b2}.ansi-white-intense-bg{background-color:#a1a6b2}.ansi-default-inverse-fg{color:#fff}.ansi-default-inverse-bg{background-color:#000}.ansi-bold{font-weight:bold}.ansi-underline{text-decoration:underline}:root{--quarto-body-bg: #fff;--quarto-body-color: #373a3c;--quarto-text-muted: #6c757d;--quarto-border-color: #dee2e6;--quarto-border-width: 1px;--quarto-border-radius: 0.25rem}table.gt_table{color:var(--quarto-body-color);font-size:1em;width:100%;background-color:rgba(0,0,0,0);border-top-width:inherit;border-bottom-width:inherit;border-color:var(--quarto-border-color)}table.gt_table th.gt_column_spanner_outer{color:var(--quarto-body-color);background-color:rgba(0,0,0,0);border-top-width:inherit;border-bottom-width:inherit;border-color:var(--quarto-border-color)}table.gt_table th.gt_col_heading{color:var(--quarto-body-color);font-weight:bold;background-color:rgba(0,0,0,0)}table.gt_table thead.gt_col_headings{border-bottom:1px solid currentColor;border-top-width:inherit;border-top-color:var(--quarto-border-color)}table.gt_table thead.gt_col_headings:not(:first-child){border-top-width:1px;border-top-color:var(--quarto-border-color)}table.gt_table td.gt_row{border-bottom-width:1px;border-bottom-color:var(--quarto-border-color);border-top-width:0px}table.gt_table tbody.gt_table_body{border-top-width:1px;border-bottom-width:1px;border-bottom-color:var(--quarto-border-color);border-top-color:currentColor}div.columns{display:initial;gap:initial}div.column{display:inline-block;overflow-x:initial;vertical-align:top;width:50%}.code-annotation-tip-content{word-wrap:break-word}.code-annotation-container-hidden{display:none !important}dl.code-annotation-container-grid{display:grid;grid-template-columns:min-content auto}dl.code-annotation-container-grid dt{grid-column:1}dl.code-annotation-container-grid dd{grid-column:2}pre.sourceCode.code-annotation-code{padding-right:0}code.sourceCode .code-annotation-anchor{z-index:100;position:absolute;right:.5em;left:inherit;background-color:rgba(0,0,0,0)}:root{--mermaid-bg-color: #fff;--mermaid-edge-color: #373a3c;--mermaid-node-fg-color: #373a3c;--mermaid-fg-color: #373a3c;--mermaid-fg-color--lighter: #4f5457;--mermaid-fg-color--lightest: #686d71;--mermaid-font-family: Source Sans Pro, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;--mermaid-label-bg-color: #fff;--mermaid-label-fg-color: #2780e3;--mermaid-node-bg-color: rgba(39, 128, 227, 0.1);--mermaid-node-fg-color: #373a3c}@media print{:root{font-size:11pt}#quarto-sidebar,#TOC,.nav-page{display:none}.page-columns .content{grid-column-start:page-start}.fixed-top{position:relative}.panel-caption,.figure-caption,figcaption{color:#666}}.code-copy-button{position:absolute;top:0;right:0;border:0;margin-top:5px;margin-right:5px;background-color:rgba(0,0,0,0);z-index:3}.code-copy-button:focus{outline:none}.code-copy-button-tooltip{font-size:.75em}pre.sourceCode:hover>.code-copy-button>.bi::before{display:inline-block;height:1rem;width:1rem;content:"";vertical-align:-0.125em;background-image:url('data:image/svg+xml,');background-repeat:no-repeat;background-size:1rem 1rem}pre.sourceCode:hover>.code-copy-button-checked>.bi::before{background-image:url('data:image/svg+xml,')}pre.sourceCode:hover>.code-copy-button:hover>.bi::before{background-image:url('data:image/svg+xml,')}pre.sourceCode:hover>.code-copy-button-checked:hover>.bi::before{background-image:url('data:image/svg+xml,')}main ol ol,main ul ul,main ol ul,main ul ol{margin-bottom:1em}ul>li:not(:has(>p))>ul,ol>li:not(:has(>p))>ul,ul>li:not(:has(>p))>ol,ol>li:not(:has(>p))>ol{margin-bottom:0}ul>li:not(:has(>p))>ul>li:has(>p),ol>li:not(:has(>p))>ul>li:has(>p),ul>li:not(:has(>p))>ol>li:has(>p),ol>li:not(:has(>p))>ol>li:has(>p){margin-top:1rem}body{margin:0}main.page-columns>header>h1.title,main.page-columns>header>.title.h1{margin-bottom:0}@media(min-width: 992px){body .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset] 35px [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(500px, calc( 850px - 3em )) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.fullcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset] 35px [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(500px, calc( 850px - 3em )) [body-content-end] 1.5em [body-end] 35px [body-end-outset] 35px [page-end-inset page-end] 5fr [screen-end-inset] 1.5em}body.slimcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset] 35px [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(500px, calc( 850px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.listing:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc( 850px - 3em )) [body-content-end] 3em [body-end] 50px [body-end-outset] minmax(0px, 250px) [page-end-inset] minmax(50px, 100px) [page-end] 1fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 175px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc( 800px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 175px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc( 800px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] minmax(25px, 50px) [page-start-inset] minmax(50px, 150px) [body-start-outset] minmax(25px, 50px) [body-start] 1.5em [body-content-start] minmax(500px, calc( 800px - 3em )) [body-content-end] 1.5em [body-end] minmax(25px, 50px) [body-end-outset] minmax(50px, 150px) [page-end-inset] minmax(25px, 50px) [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc( 1000px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(50px, 100px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc( 1000px - 3em )) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 50px [page-start-inset] minmax(50px, 150px) [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc( 800px - 3em )) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(450px, calc( 750px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc( 1000px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 50px [page-start-inset] minmax(50px, 150px) [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(450px, calc( 750px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(50px, 150px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] minmax(25px, 50px) [page-start-inset] minmax(50px, 150px) [body-start-outset] minmax(25px, 50px) [body-start] 1.5em [body-content-start] minmax(500px, calc( 800px - 3em )) [body-content-end] 1.5em [body-end] minmax(25px, 50px) [body-end-outset] minmax(50px, 150px) [page-end-inset] minmax(25px, 50px) [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}}@media(max-width: 991.98px){body .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc( 800px - 3em )) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.fullcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc( 800px - 3em )) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.slimcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc( 800px - 3em )) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.listing:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc( 1250px - 3em )) [body-content-end body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 145px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc( 800px - 3em )) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 145px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc( 800px - 3em )) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1.5em [body-content-start] minmax(500px, calc( 750px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(75px, 150px) [page-end-inset] 25px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc( 750px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(25px, 50px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc( 1000px - 3em )) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1em [body-content-start] minmax(500px, calc( 800px - 3em )) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 4fr [screen-end-inset] 1.5em [screen-end]}body.docked.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc( 750px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(25px, 50px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc( 750px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(25px, 50px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1em [body-content-start] minmax(500px, calc( 750px - 3em )) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 4fr [screen-end-inset] 1.5em [screen-end]}body.floating.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1em [body-content-start] minmax(500px, calc( 750px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(75px, 150px) [page-end-inset] 25px [page-end] 4fr [screen-end-inset] 1.5em [screen-end]}}@media(max-width: 767.98px){body .page-columns,body.fullcontent:not(.floating):not(.docked) .page-columns,body.slimcontent:not(.floating):not(.docked) .page-columns,body.docked .page-columns,body.docked.slimcontent .page-columns,body.docked.fullcontent .page-columns,body.floating .page-columns,body.floating.slimcontent .page-columns,body.floating.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(0px, 1fr) [body-content-end body-end body-end-outset page-end-inset page-end screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(0px, 1fr) [body-content-end body-end body-end-outset page-end-inset page-end screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(0px, 1fr) [body-content-end body-end body-end-outset page-end-inset page-end screen-end-inset] 1.5em [screen-end]}nav[role=doc-toc]{display:none}}body,.page-row-navigation{grid-template-rows:[page-top] max-content [contents-top] max-content [contents-bottom] max-content [page-bottom]}.page-rows-contents{grid-template-rows:[content-top] minmax(max-content, 1fr) [content-bottom] minmax(60px, max-content) [page-bottom]}.page-full{grid-column:screen-start/screen-end !important}.page-columns>*{grid-column:body-content-start/body-content-end}.page-columns.column-page>*{grid-column:page-start/page-end}.page-columns.column-page-left>*{grid-column:page-start/body-content-end}.page-columns.column-page-right>*{grid-column:body-content-start/page-end}.page-rows{grid-auto-rows:auto}.header{grid-column:screen-start/screen-end;grid-row:page-top/contents-top}#quarto-content{padding:0;grid-column:screen-start/screen-end;grid-row:contents-top/contents-bottom}body.floating .sidebar.sidebar-navigation{grid-column:page-start/body-start;grid-row:content-top/page-bottom}body.docked .sidebar.sidebar-navigation{grid-column:screen-start/body-start;grid-row:content-top/page-bottom}.sidebar.toc-left{grid-column:page-start/body-start;grid-row:content-top/page-bottom}.sidebar.margin-sidebar{grid-column:body-end/page-end;grid-row:content-top/page-bottom}.page-columns .content{grid-column:body-content-start/body-content-end;grid-row:content-top/content-bottom;align-content:flex-start}.page-columns .page-navigation{grid-column:body-content-start/body-content-end;grid-row:content-bottom/page-bottom}.page-columns .footer{grid-column:screen-start/screen-end;grid-row:contents-bottom/page-bottom}.page-columns .column-body{grid-column:body-content-start/body-content-end}.page-columns .column-body-fullbleed{grid-column:body-start/body-end}.page-columns .column-body-outset{grid-column:body-start-outset/body-end-outset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-body-outset table{background:#fff}.page-columns .column-body-outset-left{grid-column:body-start-outset/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-body-outset-left table{background:#fff}.page-columns .column-body-outset-right{grid-column:body-content-start/body-end-outset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-body-outset-right table{background:#fff}.page-columns .column-page{grid-column:page-start/page-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-page table{background:#fff}.page-columns .column-page-inset{grid-column:page-start-inset/page-end-inset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-page-inset table{background:#fff}.page-columns .column-page-inset-left{grid-column:page-start-inset/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-page-inset-left table{background:#fff}.page-columns .column-page-inset-right{grid-column:body-content-start/page-end-inset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-page-inset-right figcaption table{background:#fff}.page-columns .column-page-left{grid-column:page-start/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-page-left table{background:#fff}.page-columns .column-page-right{grid-column:body-content-start/page-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-page-right figcaption table{background:#fff}#quarto-content.page-columns #quarto-margin-sidebar,#quarto-content.page-columns #quarto-sidebar{z-index:1}@media(max-width: 991.98px){#quarto-content.page-columns #quarto-margin-sidebar.collapse,#quarto-content.page-columns #quarto-sidebar.collapse,#quarto-content.page-columns #quarto-margin-sidebar.collapsing,#quarto-content.page-columns #quarto-sidebar.collapsing{z-index:1055}}#quarto-content.page-columns main.column-page,#quarto-content.page-columns main.column-page-right,#quarto-content.page-columns main.column-page-left{z-index:0}.page-columns .column-screen-inset{grid-column:screen-start-inset/screen-end-inset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-inset table{background:#fff}.page-columns .column-screen-inset-left{grid-column:screen-start-inset/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-inset-left table{background:#fff}.page-columns .column-screen-inset-right{grid-column:body-content-start/screen-end-inset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-inset-right table{background:#fff}.page-columns .column-screen{grid-column:screen-start/screen-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen table{background:#fff}.page-columns .column-screen-left{grid-column:screen-start/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-left table{background:#fff}.page-columns .column-screen-right{grid-column:body-content-start/screen-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-right table{background:#fff}.page-columns .column-screen-inset-shaded{grid-column:screen-start/screen-end;padding:1em;background:#f8f9fa;z-index:998;transform:translate3d(0, 0, 0);margin-bottom:1em}.zindex-content{z-index:998;transform:translate3d(0, 0, 0)}.zindex-modal{z-index:1055;transform:translate3d(0, 0, 0)}.zindex-over-content{z-index:999;transform:translate3d(0, 0, 0)}img.img-fluid.column-screen,img.img-fluid.column-screen-inset-shaded,img.img-fluid.column-screen-inset,img.img-fluid.column-screen-inset-left,img.img-fluid.column-screen-inset-right,img.img-fluid.column-screen-left,img.img-fluid.column-screen-right{width:100%}@media(min-width: 992px){.margin-caption,div.aside,aside,.column-margin{grid-column:body-end/page-end !important;z-index:998}.column-sidebar{grid-column:page-start/body-start !important;z-index:998}.column-leftmargin{grid-column:screen-start-inset/body-start !important;z-index:998}.no-row-height{height:1em;overflow:visible}}@media(max-width: 991.98px){.margin-caption,div.aside,aside,.column-margin{grid-column:body-end/page-end !important;z-index:998}.no-row-height{height:1em;overflow:visible}.page-columns.page-full{overflow:visible}.page-columns.toc-left .margin-caption,.page-columns.toc-left div.aside,.page-columns.toc-left aside,.page-columns.toc-left .column-margin{grid-column:body-content-start/body-content-end !important;z-index:998;transform:translate3d(0, 0, 0)}.page-columns.toc-left .no-row-height{height:initial;overflow:initial}}@media(max-width: 767.98px){.margin-caption,div.aside,aside,.column-margin{grid-column:body-content-start/body-content-end !important;z-index:998;transform:translate3d(0, 0, 0)}.no-row-height{height:initial;overflow:initial}#quarto-margin-sidebar{display:none}#quarto-sidebar-toc-left{display:none}.hidden-sm{display:none}}.panel-grid{display:grid;grid-template-rows:repeat(1, 1fr);grid-template-columns:repeat(24, 1fr);gap:1em}.panel-grid .g-col-1{grid-column:auto/span 1}.panel-grid .g-col-2{grid-column:auto/span 2}.panel-grid .g-col-3{grid-column:auto/span 3}.panel-grid .g-col-4{grid-column:auto/span 4}.panel-grid .g-col-5{grid-column:auto/span 5}.panel-grid .g-col-6{grid-column:auto/span 6}.panel-grid .g-col-7{grid-column:auto/span 7}.panel-grid .g-col-8{grid-column:auto/span 8}.panel-grid .g-col-9{grid-column:auto/span 9}.panel-grid .g-col-10{grid-column:auto/span 10}.panel-grid .g-col-11{grid-column:auto/span 11}.panel-grid .g-col-12{grid-column:auto/span 12}.panel-grid .g-col-13{grid-column:auto/span 13}.panel-grid .g-col-14{grid-column:auto/span 14}.panel-grid .g-col-15{grid-column:auto/span 15}.panel-grid .g-col-16{grid-column:auto/span 16}.panel-grid .g-col-17{grid-column:auto/span 17}.panel-grid .g-col-18{grid-column:auto/span 18}.panel-grid .g-col-19{grid-column:auto/span 19}.panel-grid .g-col-20{grid-column:auto/span 20}.panel-grid .g-col-21{grid-column:auto/span 21}.panel-grid .g-col-22{grid-column:auto/span 22}.panel-grid .g-col-23{grid-column:auto/span 23}.panel-grid .g-col-24{grid-column:auto/span 24}.panel-grid .g-start-1{grid-column-start:1}.panel-grid .g-start-2{grid-column-start:2}.panel-grid .g-start-3{grid-column-start:3}.panel-grid .g-start-4{grid-column-start:4}.panel-grid .g-start-5{grid-column-start:5}.panel-grid .g-start-6{grid-column-start:6}.panel-grid .g-start-7{grid-column-start:7}.panel-grid .g-start-8{grid-column-start:8}.panel-grid .g-start-9{grid-column-start:9}.panel-grid .g-start-10{grid-column-start:10}.panel-grid .g-start-11{grid-column-start:11}.panel-grid .g-start-12{grid-column-start:12}.panel-grid .g-start-13{grid-column-start:13}.panel-grid .g-start-14{grid-column-start:14}.panel-grid .g-start-15{grid-column-start:15}.panel-grid .g-start-16{grid-column-start:16}.panel-grid .g-start-17{grid-column-start:17}.panel-grid .g-start-18{grid-column-start:18}.panel-grid .g-start-19{grid-column-start:19}.panel-grid .g-start-20{grid-column-start:20}.panel-grid .g-start-21{grid-column-start:21}.panel-grid .g-start-22{grid-column-start:22}.panel-grid .g-start-23{grid-column-start:23}@media(min-width: 576px){.panel-grid .g-col-sm-1{grid-column:auto/span 1}.panel-grid .g-col-sm-2{grid-column:auto/span 2}.panel-grid .g-col-sm-3{grid-column:auto/span 3}.panel-grid .g-col-sm-4{grid-column:auto/span 4}.panel-grid .g-col-sm-5{grid-column:auto/span 5}.panel-grid .g-col-sm-6{grid-column:auto/span 6}.panel-grid .g-col-sm-7{grid-column:auto/span 7}.panel-grid .g-col-sm-8{grid-column:auto/span 8}.panel-grid .g-col-sm-9{grid-column:auto/span 9}.panel-grid .g-col-sm-10{grid-column:auto/span 10}.panel-grid .g-col-sm-11{grid-column:auto/span 11}.panel-grid .g-col-sm-12{grid-column:auto/span 12}.panel-grid .g-col-sm-13{grid-column:auto/span 13}.panel-grid .g-col-sm-14{grid-column:auto/span 14}.panel-grid .g-col-sm-15{grid-column:auto/span 15}.panel-grid .g-col-sm-16{grid-column:auto/span 16}.panel-grid .g-col-sm-17{grid-column:auto/span 17}.panel-grid .g-col-sm-18{grid-column:auto/span 18}.panel-grid .g-col-sm-19{grid-column:auto/span 19}.panel-grid .g-col-sm-20{grid-column:auto/span 20}.panel-grid .g-col-sm-21{grid-column:auto/span 21}.panel-grid .g-col-sm-22{grid-column:auto/span 22}.panel-grid .g-col-sm-23{grid-column:auto/span 23}.panel-grid .g-col-sm-24{grid-column:auto/span 24}.panel-grid .g-start-sm-1{grid-column-start:1}.panel-grid .g-start-sm-2{grid-column-start:2}.panel-grid .g-start-sm-3{grid-column-start:3}.panel-grid .g-start-sm-4{grid-column-start:4}.panel-grid .g-start-sm-5{grid-column-start:5}.panel-grid .g-start-sm-6{grid-column-start:6}.panel-grid .g-start-sm-7{grid-column-start:7}.panel-grid .g-start-sm-8{grid-column-start:8}.panel-grid .g-start-sm-9{grid-column-start:9}.panel-grid .g-start-sm-10{grid-column-start:10}.panel-grid .g-start-sm-11{grid-column-start:11}.panel-grid .g-start-sm-12{grid-column-start:12}.panel-grid .g-start-sm-13{grid-column-start:13}.panel-grid .g-start-sm-14{grid-column-start:14}.panel-grid .g-start-sm-15{grid-column-start:15}.panel-grid .g-start-sm-16{grid-column-start:16}.panel-grid .g-start-sm-17{grid-column-start:17}.panel-grid .g-start-sm-18{grid-column-start:18}.panel-grid .g-start-sm-19{grid-column-start:19}.panel-grid .g-start-sm-20{grid-column-start:20}.panel-grid .g-start-sm-21{grid-column-start:21}.panel-grid .g-start-sm-22{grid-column-start:22}.panel-grid .g-start-sm-23{grid-column-start:23}}@media(min-width: 768px){.panel-grid .g-col-md-1{grid-column:auto/span 1}.panel-grid .g-col-md-2{grid-column:auto/span 2}.panel-grid .g-col-md-3{grid-column:auto/span 3}.panel-grid .g-col-md-4{grid-column:auto/span 4}.panel-grid .g-col-md-5{grid-column:auto/span 5}.panel-grid .g-col-md-6{grid-column:auto/span 6}.panel-grid .g-col-md-7{grid-column:auto/span 7}.panel-grid .g-col-md-8{grid-column:auto/span 8}.panel-grid .g-col-md-9{grid-column:auto/span 9}.panel-grid .g-col-md-10{grid-column:auto/span 10}.panel-grid .g-col-md-11{grid-column:auto/span 11}.panel-grid .g-col-md-12{grid-column:auto/span 12}.panel-grid .g-col-md-13{grid-column:auto/span 13}.panel-grid .g-col-md-14{grid-column:auto/span 14}.panel-grid .g-col-md-15{grid-column:auto/span 15}.panel-grid .g-col-md-16{grid-column:auto/span 16}.panel-grid .g-col-md-17{grid-column:auto/span 17}.panel-grid .g-col-md-18{grid-column:auto/span 18}.panel-grid .g-col-md-19{grid-column:auto/span 19}.panel-grid .g-col-md-20{grid-column:auto/span 20}.panel-grid .g-col-md-21{grid-column:auto/span 21}.panel-grid .g-col-md-22{grid-column:auto/span 22}.panel-grid .g-col-md-23{grid-column:auto/span 23}.panel-grid .g-col-md-24{grid-column:auto/span 24}.panel-grid .g-start-md-1{grid-column-start:1}.panel-grid .g-start-md-2{grid-column-start:2}.panel-grid .g-start-md-3{grid-column-start:3}.panel-grid .g-start-md-4{grid-column-start:4}.panel-grid .g-start-md-5{grid-column-start:5}.panel-grid .g-start-md-6{grid-column-start:6}.panel-grid .g-start-md-7{grid-column-start:7}.panel-grid .g-start-md-8{grid-column-start:8}.panel-grid .g-start-md-9{grid-column-start:9}.panel-grid .g-start-md-10{grid-column-start:10}.panel-grid .g-start-md-11{grid-column-start:11}.panel-grid .g-start-md-12{grid-column-start:12}.panel-grid .g-start-md-13{grid-column-start:13}.panel-grid .g-start-md-14{grid-column-start:14}.panel-grid .g-start-md-15{grid-column-start:15}.panel-grid .g-start-md-16{grid-column-start:16}.panel-grid .g-start-md-17{grid-column-start:17}.panel-grid .g-start-md-18{grid-column-start:18}.panel-grid .g-start-md-19{grid-column-start:19}.panel-grid .g-start-md-20{grid-column-start:20}.panel-grid .g-start-md-21{grid-column-start:21}.panel-grid .g-start-md-22{grid-column-start:22}.panel-grid .g-start-md-23{grid-column-start:23}}@media(min-width: 992px){.panel-grid .g-col-lg-1{grid-column:auto/span 1}.panel-grid .g-col-lg-2{grid-column:auto/span 2}.panel-grid .g-col-lg-3{grid-column:auto/span 3}.panel-grid .g-col-lg-4{grid-column:auto/span 4}.panel-grid .g-col-lg-5{grid-column:auto/span 5}.panel-grid .g-col-lg-6{grid-column:auto/span 6}.panel-grid .g-col-lg-7{grid-column:auto/span 7}.panel-grid .g-col-lg-8{grid-column:auto/span 8}.panel-grid .g-col-lg-9{grid-column:auto/span 9}.panel-grid .g-col-lg-10{grid-column:auto/span 10}.panel-grid .g-col-lg-11{grid-column:auto/span 11}.panel-grid .g-col-lg-12{grid-column:auto/span 12}.panel-grid .g-col-lg-13{grid-column:auto/span 13}.panel-grid .g-col-lg-14{grid-column:auto/span 14}.panel-grid .g-col-lg-15{grid-column:auto/span 15}.panel-grid .g-col-lg-16{grid-column:auto/span 16}.panel-grid .g-col-lg-17{grid-column:auto/span 17}.panel-grid .g-col-lg-18{grid-column:auto/span 18}.panel-grid .g-col-lg-19{grid-column:auto/span 19}.panel-grid .g-col-lg-20{grid-column:auto/span 20}.panel-grid .g-col-lg-21{grid-column:auto/span 21}.panel-grid .g-col-lg-22{grid-column:auto/span 22}.panel-grid .g-col-lg-23{grid-column:auto/span 23}.panel-grid .g-col-lg-24{grid-column:auto/span 24}.panel-grid .g-start-lg-1{grid-column-start:1}.panel-grid .g-start-lg-2{grid-column-start:2}.panel-grid .g-start-lg-3{grid-column-start:3}.panel-grid .g-start-lg-4{grid-column-start:4}.panel-grid .g-start-lg-5{grid-column-start:5}.panel-grid .g-start-lg-6{grid-column-start:6}.panel-grid .g-start-lg-7{grid-column-start:7}.panel-grid .g-start-lg-8{grid-column-start:8}.panel-grid .g-start-lg-9{grid-column-start:9}.panel-grid .g-start-lg-10{grid-column-start:10}.panel-grid .g-start-lg-11{grid-column-start:11}.panel-grid .g-start-lg-12{grid-column-start:12}.panel-grid .g-start-lg-13{grid-column-start:13}.panel-grid .g-start-lg-14{grid-column-start:14}.panel-grid .g-start-lg-15{grid-column-start:15}.panel-grid .g-start-lg-16{grid-column-start:16}.panel-grid .g-start-lg-17{grid-column-start:17}.panel-grid .g-start-lg-18{grid-column-start:18}.panel-grid .g-start-lg-19{grid-column-start:19}.panel-grid .g-start-lg-20{grid-column-start:20}.panel-grid .g-start-lg-21{grid-column-start:21}.panel-grid .g-start-lg-22{grid-column-start:22}.panel-grid .g-start-lg-23{grid-column-start:23}}@media(min-width: 1200px){.panel-grid .g-col-xl-1{grid-column:auto/span 1}.panel-grid .g-col-xl-2{grid-column:auto/span 2}.panel-grid .g-col-xl-3{grid-column:auto/span 3}.panel-grid .g-col-xl-4{grid-column:auto/span 4}.panel-grid .g-col-xl-5{grid-column:auto/span 5}.panel-grid .g-col-xl-6{grid-column:auto/span 6}.panel-grid .g-col-xl-7{grid-column:auto/span 7}.panel-grid .g-col-xl-8{grid-column:auto/span 8}.panel-grid .g-col-xl-9{grid-column:auto/span 9}.panel-grid .g-col-xl-10{grid-column:auto/span 10}.panel-grid .g-col-xl-11{grid-column:auto/span 11}.panel-grid .g-col-xl-12{grid-column:auto/span 12}.panel-grid .g-col-xl-13{grid-column:auto/span 13}.panel-grid .g-col-xl-14{grid-column:auto/span 14}.panel-grid .g-col-xl-15{grid-column:auto/span 15}.panel-grid .g-col-xl-16{grid-column:auto/span 16}.panel-grid .g-col-xl-17{grid-column:auto/span 17}.panel-grid .g-col-xl-18{grid-column:auto/span 18}.panel-grid .g-col-xl-19{grid-column:auto/span 19}.panel-grid .g-col-xl-20{grid-column:auto/span 20}.panel-grid .g-col-xl-21{grid-column:auto/span 21}.panel-grid .g-col-xl-22{grid-column:auto/span 22}.panel-grid .g-col-xl-23{grid-column:auto/span 23}.panel-grid .g-col-xl-24{grid-column:auto/span 24}.panel-grid .g-start-xl-1{grid-column-start:1}.panel-grid .g-start-xl-2{grid-column-start:2}.panel-grid .g-start-xl-3{grid-column-start:3}.panel-grid .g-start-xl-4{grid-column-start:4}.panel-grid .g-start-xl-5{grid-column-start:5}.panel-grid .g-start-xl-6{grid-column-start:6}.panel-grid .g-start-xl-7{grid-column-start:7}.panel-grid .g-start-xl-8{grid-column-start:8}.panel-grid .g-start-xl-9{grid-column-start:9}.panel-grid .g-start-xl-10{grid-column-start:10}.panel-grid .g-start-xl-11{grid-column-start:11}.panel-grid .g-start-xl-12{grid-column-start:12}.panel-grid .g-start-xl-13{grid-column-start:13}.panel-grid .g-start-xl-14{grid-column-start:14}.panel-grid .g-start-xl-15{grid-column-start:15}.panel-grid .g-start-xl-16{grid-column-start:16}.panel-grid .g-start-xl-17{grid-column-start:17}.panel-grid .g-start-xl-18{grid-column-start:18}.panel-grid .g-start-xl-19{grid-column-start:19}.panel-grid .g-start-xl-20{grid-column-start:20}.panel-grid .g-start-xl-21{grid-column-start:21}.panel-grid .g-start-xl-22{grid-column-start:22}.panel-grid .g-start-xl-23{grid-column-start:23}}@media(min-width: 1400px){.panel-grid .g-col-xxl-1{grid-column:auto/span 1}.panel-grid .g-col-xxl-2{grid-column:auto/span 2}.panel-grid .g-col-xxl-3{grid-column:auto/span 3}.panel-grid .g-col-xxl-4{grid-column:auto/span 4}.panel-grid .g-col-xxl-5{grid-column:auto/span 5}.panel-grid .g-col-xxl-6{grid-column:auto/span 6}.panel-grid .g-col-xxl-7{grid-column:auto/span 7}.panel-grid .g-col-xxl-8{grid-column:auto/span 8}.panel-grid .g-col-xxl-9{grid-column:auto/span 9}.panel-grid .g-col-xxl-10{grid-column:auto/span 10}.panel-grid .g-col-xxl-11{grid-column:auto/span 11}.panel-grid .g-col-xxl-12{grid-column:auto/span 12}.panel-grid .g-col-xxl-13{grid-column:auto/span 13}.panel-grid .g-col-xxl-14{grid-column:auto/span 14}.panel-grid .g-col-xxl-15{grid-column:auto/span 15}.panel-grid .g-col-xxl-16{grid-column:auto/span 16}.panel-grid .g-col-xxl-17{grid-column:auto/span 17}.panel-grid .g-col-xxl-18{grid-column:auto/span 18}.panel-grid .g-col-xxl-19{grid-column:auto/span 19}.panel-grid .g-col-xxl-20{grid-column:auto/span 20}.panel-grid .g-col-xxl-21{grid-column:auto/span 21}.panel-grid .g-col-xxl-22{grid-column:auto/span 22}.panel-grid .g-col-xxl-23{grid-column:auto/span 23}.panel-grid .g-col-xxl-24{grid-column:auto/span 24}.panel-grid .g-start-xxl-1{grid-column-start:1}.panel-grid .g-start-xxl-2{grid-column-start:2}.panel-grid .g-start-xxl-3{grid-column-start:3}.panel-grid .g-start-xxl-4{grid-column-start:4}.panel-grid .g-start-xxl-5{grid-column-start:5}.panel-grid .g-start-xxl-6{grid-column-start:6}.panel-grid .g-start-xxl-7{grid-column-start:7}.panel-grid .g-start-xxl-8{grid-column-start:8}.panel-grid .g-start-xxl-9{grid-column-start:9}.panel-grid .g-start-xxl-10{grid-column-start:10}.panel-grid .g-start-xxl-11{grid-column-start:11}.panel-grid .g-start-xxl-12{grid-column-start:12}.panel-grid .g-start-xxl-13{grid-column-start:13}.panel-grid .g-start-xxl-14{grid-column-start:14}.panel-grid .g-start-xxl-15{grid-column-start:15}.panel-grid .g-start-xxl-16{grid-column-start:16}.panel-grid .g-start-xxl-17{grid-column-start:17}.panel-grid .g-start-xxl-18{grid-column-start:18}.panel-grid .g-start-xxl-19{grid-column-start:19}.panel-grid .g-start-xxl-20{grid-column-start:20}.panel-grid .g-start-xxl-21{grid-column-start:21}.panel-grid .g-start-xxl-22{grid-column-start:22}.panel-grid .g-start-xxl-23{grid-column-start:23}}main{margin-top:1em;margin-bottom:1em}h1,.h1,h2,.h2{opacity:.9;margin-top:2rem;margin-bottom:1rem;font-weight:600}h1.title,.title.h1{margin-top:0}h2,.h2{border-bottom:1px solid #dee2e6;padding-bottom:.5rem}h3,.h3{font-weight:600}h3,.h3,h4,.h4{opacity:.9;margin-top:1.5rem}h5,.h5,h6,.h6{opacity:.9}.header-section-number{color:#747a7f}.nav-link.active .header-section-number{color:inherit}mark,.mark{padding:0em}.panel-caption,caption,.figure-caption{font-size:.9rem}.panel-caption,.figure-caption,figcaption{color:#747a7f}.table-caption,caption{color:#373a3c}.quarto-layout-cell[data-ref-parent] caption{color:#747a7f}.column-margin figcaption,.margin-caption,div.aside,aside,.column-margin{color:#747a7f;font-size:.825rem}.panel-caption.margin-caption{text-align:inherit}.column-margin.column-container p{margin-bottom:0}.column-margin.column-container>*:not(.collapse){padding-top:.5em;padding-bottom:.5em;display:block}.column-margin.column-container>*.collapse:not(.show){display:none}@media(min-width: 768px){.column-margin.column-container .callout-margin-content:first-child{margin-top:4.5em}.column-margin.column-container .callout-margin-content-simple:first-child{margin-top:3.5em}}.margin-caption>*{padding-top:.5em;padding-bottom:.5em}@media(max-width: 767.98px){.quarto-layout-row{flex-direction:column}}.nav-tabs .nav-item{margin-top:1px;cursor:pointer}.tab-content{margin-top:0px;border-left:#dee2e6 1px solid;border-right:#dee2e6 1px solid;border-bottom:#dee2e6 1px solid;margin-left:0;padding:1em;margin-bottom:1em}@media(max-width: 767.98px){.layout-sidebar{margin-left:0;margin-right:0}}.panel-sidebar,.panel-sidebar .form-control,.panel-input,.panel-input .form-control,.selectize-dropdown{font-size:.9rem}.panel-sidebar .form-control,.panel-input .form-control{padding-top:.1rem}.tab-pane div.sourceCode{margin-top:0px}.tab-pane>p{padding-top:1em}.tab-content>.tab-pane:not(.active){display:none !important}div.sourceCode{background-color:rgba(233,236,239,.65);border:1px solid rgba(233,236,239,.65);border-radius:.25rem}pre.sourceCode{background-color:rgba(0,0,0,0)}pre.sourceCode{border:none;font-size:.875em;overflow:visible !important;padding:.4em}.callout pre.sourceCode{padding-left:0}div.sourceCode{overflow-y:hidden}.callout div.sourceCode{margin-left:initial}.blockquote{font-size:inherit;padding-left:1rem;padding-right:1.5rem;color:#747a7f}.blockquote h1:first-child,.blockquote .h1:first-child,.blockquote h2:first-child,.blockquote .h2:first-child,.blockquote h3:first-child,.blockquote .h3:first-child,.blockquote h4:first-child,.blockquote .h4:first-child,.blockquote h5:first-child,.blockquote .h5:first-child{margin-top:0}pre{background-color:initial;padding:initial;border:initial}p code:not(.sourceCode),li code:not(.sourceCode),td code:not(.sourceCode){background-color:#f7f7f7;padding:.2em}nav p code:not(.sourceCode),nav li code:not(.sourceCode),nav td code:not(.sourceCode){background-color:rgba(0,0,0,0);padding:0}td code:not(.sourceCode){white-space:pre-wrap}#quarto-embedded-source-code-modal>.modal-dialog{max-width:1000px;padding-left:1.75rem;padding-right:1.75rem}#quarto-embedded-source-code-modal>.modal-dialog>.modal-content>.modal-body{padding:0}#quarto-embedded-source-code-modal>.modal-dialog>.modal-content>.modal-body div.sourceCode{margin:0;padding:.2rem .2rem;border-radius:0px;border:none}#quarto-embedded-source-code-modal>.modal-dialog>.modal-content>.modal-header{padding:.7rem}.code-tools-button{font-size:1rem;padding:.15rem .15rem;margin-left:5px;color:#6c757d;background-color:rgba(0,0,0,0);transition:initial;cursor:pointer}.code-tools-button>.bi::before{display:inline-block;height:1rem;width:1rem;content:"";vertical-align:-0.125em;background-image:url('data:image/svg+xml,');background-repeat:no-repeat;background-size:1rem 1rem}.code-tools-button:hover>.bi::before{background-image:url('data:image/svg+xml,')}#quarto-embedded-source-code-modal .code-copy-button>.bi::before{background-image:url('data:image/svg+xml,')}#quarto-embedded-source-code-modal .code-copy-button-checked>.bi::before{background-image:url('data:image/svg+xml,')}.sidebar{will-change:top;transition:top 200ms linear;position:sticky;overflow-y:auto;padding-top:1.2em;max-height:100vh}.sidebar.toc-left,.sidebar.margin-sidebar{top:0px;padding-top:1em}.sidebar.toc-left>*,.sidebar.margin-sidebar>*{padding-top:.5em}.sidebar.quarto-banner-title-block-sidebar>*{padding-top:1.65em}figure .quarto-notebook-link{margin-top:.5em}.quarto-notebook-link{font-size:.75em;color:#6c757d;margin-bottom:1em;text-decoration:none;display:block}.quarto-notebook-link:hover{text-decoration:underline;color:#2780e3}.quarto-notebook-link::before{display:inline-block;height:.75rem;width:.75rem;margin-bottom:0em;margin-right:.25em;content:"";vertical-align:-0.125em;background-image:url('data:image/svg+xml,');background-repeat:no-repeat;background-size:.75rem .75rem}.quarto-alternate-notebooks i.bi,.quarto-alternate-formats i.bi{margin-right:.4em}.quarto-notebook .cell-container{display:flex}.quarto-notebook .cell-container .cell{flex-grow:4}.quarto-notebook .cell-container .cell-decorator{padding-top:1.5em;padding-right:1em;text-align:right}.quarto-notebook h2,.quarto-notebook .h2{border-bottom:none}.sidebar .quarto-alternate-formats a,.sidebar .quarto-alternate-notebooks a{text-decoration:none}.sidebar .quarto-alternate-formats a:hover,.sidebar .quarto-alternate-notebooks a:hover{color:#2780e3}.sidebar .quarto-alternate-notebooks h2,.sidebar .quarto-alternate-notebooks .h2,.sidebar .quarto-alternate-formats h2,.sidebar .quarto-alternate-formats .h2,.sidebar nav[role=doc-toc]>h2,.sidebar nav[role=doc-toc]>.h2{font-size:.875rem;font-weight:400;margin-bottom:.5rem;margin-top:.3rem;font-family:inherit;border-bottom:0;padding-bottom:0;padding-top:0px}.sidebar .quarto-alternate-notebooks h2,.sidebar .quarto-alternate-notebooks .h2,.sidebar .quarto-alternate-formats h2,.sidebar .quarto-alternate-formats .h2{margin-top:1rem}.sidebar nav[role=doc-toc]>ul a{border-left:1px solid #e9ecef;padding-left:.6rem}.sidebar .quarto-alternate-notebooks h2>ul a,.sidebar .quarto-alternate-notebooks .h2>ul a,.sidebar .quarto-alternate-formats h2>ul a,.sidebar .quarto-alternate-formats .h2>ul a{border-left:none;padding-left:.6rem}.sidebar .quarto-alternate-notebooks ul a:empty,.sidebar .quarto-alternate-formats ul a:empty,.sidebar nav[role=doc-toc]>ul a:empty{display:none}.sidebar .quarto-alternate-notebooks ul,.sidebar .quarto-alternate-formats ul,.sidebar nav[role=doc-toc] ul{padding-left:0;list-style:none;font-size:.875rem;font-weight:300}.sidebar .quarto-alternate-notebooks ul li a,.sidebar .quarto-alternate-formats ul li a,.sidebar nav[role=doc-toc]>ul li a{line-height:1.1rem;padding-bottom:.2rem;padding-top:.2rem;color:inherit}.sidebar nav[role=doc-toc] ul>li>ul>li>a{padding-left:1.2em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>a{padding-left:2.4em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>ul>li>a{padding-left:3.6em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>ul>li>ul>li>a{padding-left:4.8em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>ul>li>ul>li>ul>li>a{padding-left:6em}.sidebar nav[role=doc-toc] ul>li>a.active,.sidebar nav[role=doc-toc] ul>li>ul>li>a.active{border-left:1px solid #2780e3;color:#2780e3 !important}.sidebar nav[role=doc-toc] ul>li>a:hover,.sidebar nav[role=doc-toc] ul>li>ul>li>a:hover{color:#2780e3 !important}kbd,.kbd{color:#373a3c;background-color:#f8f9fa;border:1px solid;border-radius:5px;border-color:#dee2e6}div.hanging-indent{margin-left:1em;text-indent:-1em}.citation a,.footnote-ref{text-decoration:none}.footnotes ol{padding-left:1em}.tippy-content>*{margin-bottom:.7em}.tippy-content>*:last-child{margin-bottom:0}.table a{word-break:break-word}.table>thead{border-top-width:1px;border-top-color:#dee2e6;border-bottom:1px solid #b6babc}.callout{margin-top:1.25rem;margin-bottom:1.25rem;border-radius:.25rem;overflow-wrap:break-word}.callout .callout-title-container{overflow-wrap:anywhere}.callout.callout-style-simple{padding:.4em .7em;border-left:5px solid;border-right:1px solid #dee2e6;border-top:1px solid #dee2e6;border-bottom:1px solid #dee2e6}.callout.callout-style-default{border-left:5px solid;border-right:1px solid #dee2e6;border-top:1px solid #dee2e6;border-bottom:1px solid #dee2e6}.callout .callout-body-container{flex-grow:1}.callout.callout-style-simple .callout-body{font-size:.9rem;font-weight:400}.callout.callout-style-default .callout-body{font-size:.9rem;font-weight:400}.callout.callout-titled .callout-body{margin-top:.2em}.callout:not(.no-icon).callout-titled.callout-style-simple .callout-body{padding-left:1.6em}.callout.callout-titled>.callout-header{padding-top:.2em;margin-bottom:-0.2em}.callout.callout-style-simple>div.callout-header{border-bottom:none;font-size:.9rem;font-weight:600;opacity:75%}.callout.callout-style-default>div.callout-header{border-bottom:none;font-weight:600;opacity:85%;font-size:.9rem;padding-left:.5em;padding-right:.5em}.callout.callout-style-default div.callout-body{padding-left:.5em;padding-right:.5em}.callout.callout-style-default div.callout-body>:first-child{margin-top:.5em}.callout>div.callout-header[data-bs-toggle=collapse]{cursor:pointer}.callout.callout-style-default .callout-header[aria-expanded=false],.callout.callout-style-default .callout-header[aria-expanded=true]{padding-top:0px;margin-bottom:0px;align-items:center}.callout.callout-titled .callout-body>:last-child:not(.sourceCode),.callout.callout-titled .callout-body>div>:last-child:not(.sourceCode){margin-bottom:.5rem}.callout:not(.callout-titled) .callout-body>:first-child,.callout:not(.callout-titled) .callout-body>div>:first-child{margin-top:.25rem}.callout:not(.callout-titled) .callout-body>:last-child,.callout:not(.callout-titled) .callout-body>div>:last-child{margin-bottom:.2rem}.callout.callout-style-simple .callout-icon::before,.callout.callout-style-simple .callout-toggle::before{height:1rem;width:1rem;display:inline-block;content:"";background-repeat:no-repeat;background-size:1rem 1rem}.callout.callout-style-default .callout-icon::before,.callout.callout-style-default .callout-toggle::before{height:.9rem;width:.9rem;display:inline-block;content:"";background-repeat:no-repeat;background-size:.9rem .9rem}.callout.callout-style-default .callout-toggle::before{margin-top:5px}.callout .callout-btn-toggle .callout-toggle::before{transition:transform .2s linear}.callout .callout-header[aria-expanded=false] .callout-toggle::before{transform:rotate(-90deg)}.callout .callout-header[aria-expanded=true] .callout-toggle::before{transform:none}.callout.callout-style-simple:not(.no-icon) div.callout-icon-container{padding-top:.2em;padding-right:.55em}.callout.callout-style-default:not(.no-icon) div.callout-icon-container{padding-top:.1em;padding-right:.35em}.callout.callout-style-default:not(.no-icon) div.callout-title-container{margin-top:-1px}.callout.callout-style-default.callout-caution:not(.no-icon) div.callout-icon-container{padding-top:.3em;padding-right:.35em}.callout>.callout-body>.callout-icon-container>.no-icon,.callout>.callout-header>.callout-icon-container>.no-icon{display:none}div.callout.callout{border-left-color:#6c757d}div.callout.callout-style-default>.callout-header{background-color:#6c757d}div.callout-note.callout{border-left-color:#2780e3}div.callout-note.callout-style-default>.callout-header{background-color:#e9f2fc}div.callout-note:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-note.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-note .callout-toggle::before{background-image:url('data:image/svg+xml,')}div.callout-tip.callout{border-left-color:#3fb618}div.callout-tip.callout-style-default>.callout-header{background-color:#ecf8e8}div.callout-tip:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-tip.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-tip .callout-toggle::before{background-image:url('data:image/svg+xml,')}div.callout-warning.callout{border-left-color:#ff7518}div.callout-warning.callout-style-default>.callout-header{background-color:#fff1e8}div.callout-warning:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-warning.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-warning .callout-toggle::before{background-image:url('data:image/svg+xml,')}div.callout-caution.callout{border-left-color:#f0ad4e}div.callout-caution.callout-style-default>.callout-header{background-color:#fef7ed}div.callout-caution:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-caution.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-caution .callout-toggle::before{background-image:url('data:image/svg+xml,')}div.callout-important.callout{border-left-color:#ff0039}div.callout-important.callout-style-default>.callout-header{background-color:#ffe6eb}div.callout-important:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-important.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-important .callout-toggle::before{background-image:url('data:image/svg+xml,')}.quarto-toggle-container{display:flex;align-items:center}.quarto-reader-toggle .bi::before,.quarto-color-scheme-toggle .bi::before{display:inline-block;height:1rem;width:1rem;content:"";background-repeat:no-repeat;background-size:1rem 1rem}.sidebar-navigation{padding-left:20px}.navbar .quarto-color-scheme-toggle:not(.alternate) .bi::before{background-image:url('data:image/svg+xml,')}.navbar .quarto-color-scheme-toggle.alternate .bi::before{background-image:url('data:image/svg+xml,')}.sidebar-navigation .quarto-color-scheme-toggle:not(.alternate) .bi::before{background-image:url('data:image/svg+xml,')}.sidebar-navigation .quarto-color-scheme-toggle.alternate .bi::before{background-image:url('data:image/svg+xml,')}.quarto-sidebar-toggle{border-color:#dee2e6;border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem;border-style:solid;border-width:1px;overflow:hidden;border-top-width:0px;padding-top:0px !important}.quarto-sidebar-toggle-title{cursor:pointer;padding-bottom:2px;margin-left:.25em;text-align:center;font-weight:400;font-size:.775em}#quarto-content .quarto-sidebar-toggle{background:#fafafa}#quarto-content .quarto-sidebar-toggle-title{color:#373a3c}.quarto-sidebar-toggle-icon{color:#dee2e6;margin-right:.5em;float:right;transition:transform .2s ease}.quarto-sidebar-toggle-icon::before{padding-top:5px}.quarto-sidebar-toggle.expanded .quarto-sidebar-toggle-icon{transform:rotate(-180deg)}.quarto-sidebar-toggle.expanded .quarto-sidebar-toggle-title{border-bottom:solid #dee2e6 1px}.quarto-sidebar-toggle-contents{background-color:#fff;padding-right:10px;padding-left:10px;margin-top:0px !important;transition:max-height .5s ease}.quarto-sidebar-toggle.expanded .quarto-sidebar-toggle-contents{padding-top:1em;padding-bottom:10px}.quarto-sidebar-toggle:not(.expanded) .quarto-sidebar-toggle-contents{padding-top:0px !important;padding-bottom:0px}nav[role=doc-toc]{z-index:1020}#quarto-sidebar>*,nav[role=doc-toc]>*{transition:opacity .1s ease,border .1s ease}#quarto-sidebar.slow>*,nav[role=doc-toc].slow>*{transition:opacity .4s ease,border .4s ease}.quarto-color-scheme-toggle:not(.alternate).top-right .bi::before{background-image:url('data:image/svg+xml,')}.quarto-color-scheme-toggle.alternate.top-right .bi::before{background-image:url('data:image/svg+xml,')}#quarto-appendix.default{border-top:1px solid #dee2e6}#quarto-appendix.default{background-color:#fff;padding-top:1.5em;margin-top:2em;z-index:998}#quarto-appendix.default .quarto-appendix-heading{margin-top:0;line-height:1.4em;font-weight:600;opacity:.9;border-bottom:none;margin-bottom:0}#quarto-appendix.default .footnotes ol,#quarto-appendix.default .footnotes ol li>p:last-of-type,#quarto-appendix.default .quarto-appendix-contents>p:last-of-type{margin-bottom:0}#quarto-appendix.default .quarto-appendix-secondary-label{margin-bottom:.4em}#quarto-appendix.default .quarto-appendix-bibtex{font-size:.7em;padding:1em;border:solid 1px #dee2e6;margin-bottom:1em}#quarto-appendix.default .quarto-appendix-bibtex code.sourceCode{white-space:pre-wrap}#quarto-appendix.default .quarto-appendix-citeas{font-size:.9em;padding:1em;border:solid 1px #dee2e6;margin-bottom:1em}#quarto-appendix.default .quarto-appendix-heading{font-size:1em !important}#quarto-appendix.default *[role=doc-endnotes]>ol,#quarto-appendix.default .quarto-appendix-contents>*:not(h2):not(.h2){font-size:.9em}#quarto-appendix.default section{padding-bottom:1.5em}#quarto-appendix.default section *[role=doc-endnotes],#quarto-appendix.default section>*:not(a){opacity:.9;word-wrap:break-word}.btn.btn-quarto,div.cell-output-display .btn-quarto{color:#cbcccc;background-color:#373a3c;border-color:#373a3c}.btn.btn-quarto:hover,div.cell-output-display .btn-quarto:hover{color:#cbcccc;background-color:#555859;border-color:#4b4e50}.btn-check:focus+.btn.btn-quarto,.btn.btn-quarto:focus,.btn-check:focus+div.cell-output-display .btn-quarto,div.cell-output-display .btn-quarto:focus{color:#cbcccc;background-color:#555859;border-color:#4b4e50;box-shadow:0 0 0 .25rem rgba(77,80,82,.5)}.btn-check:checked+.btn.btn-quarto,.btn-check:active+.btn.btn-quarto,.btn.btn-quarto:active,.btn.btn-quarto.active,.show>.btn.btn-quarto.dropdown-toggle,.btn-check:checked+div.cell-output-display .btn-quarto,.btn-check:active+div.cell-output-display .btn-quarto,div.cell-output-display .btn-quarto:active,div.cell-output-display .btn-quarto.active,.show>div.cell-output-display .btn-quarto.dropdown-toggle{color:#fff;background-color:#5f6163;border-color:#4b4e50}.btn-check:checked+.btn.btn-quarto:focus,.btn-check:active+.btn.btn-quarto:focus,.btn.btn-quarto:active:focus,.btn.btn-quarto.active:focus,.show>.btn.btn-quarto.dropdown-toggle:focus,.btn-check:checked+div.cell-output-display .btn-quarto:focus,.btn-check:active+div.cell-output-display .btn-quarto:focus,div.cell-output-display .btn-quarto:active:focus,div.cell-output-display .btn-quarto.active:focus,.show>div.cell-output-display .btn-quarto.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(77,80,82,.5)}.btn.btn-quarto:disabled,.btn.btn-quarto.disabled,div.cell-output-display .btn-quarto:disabled,div.cell-output-display .btn-quarto.disabled{color:#fff;background-color:#373a3c;border-color:#373a3c}nav.quarto-secondary-nav.color-navbar{background-color:#f8f9fa;color:#545555}nav.quarto-secondary-nav.color-navbar h1,nav.quarto-secondary-nav.color-navbar .h1,nav.quarto-secondary-nav.color-navbar .quarto-btn-toggle{color:#545555}@media(max-width: 991.98px){body.nav-sidebar .quarto-title-banner{margin-bottom:0;padding-bottom:0}body.nav-sidebar #title-block-header{margin-block-end:0}}p.subtitle{margin-top:.25em;margin-bottom:.5em}code a:any-link{color:inherit;text-decoration-color:#6c757d}/*! light */div.observablehq table thead tr th{background-color:var(--bs-body-bg)}input,button,select,optgroup,textarea{background-color:var(--bs-body-bg)}.code-annotated .code-copy-button{margin-right:1.25em;margin-top:0;padding-bottom:0;padding-top:3px}.code-annotation-gutter-bg{background-color:#fff}.code-annotation-gutter{background-color:rgba(233,236,239,.65)}.code-annotation-gutter,.code-annotation-gutter-bg{height:100%;width:calc(20px + .5em);position:absolute;top:0;right:0}dl.code-annotation-container-grid dt{margin-right:1em;margin-top:.25rem}dl.code-annotation-container-grid dt{font-family:var(--bs-font-monospace);color:#4f5457;border:solid #4f5457 1px;border-radius:50%;height:22px;width:22px;line-height:22px;font-size:11px;text-align:center;vertical-align:middle;text-decoration:none}dl.code-annotation-container-grid dt[data-target-cell]{cursor:pointer}dl.code-annotation-container-grid dt[data-target-cell].code-annotation-active{color:#fff;border:solid #aaa 1px;background-color:#aaa}pre.code-annotation-code{padding-top:0;padding-bottom:0}pre.code-annotation-code code{z-index:3}#code-annotation-line-highlight-gutter{width:100%;border-top:solid rgba(170,170,170,.2666666667) 1px;border-bottom:solid rgba(170,170,170,.2666666667) 1px;z-index:2;background-color:rgba(170,170,170,.1333333333)}#code-annotation-line-highlight{margin-left:-4em;width:calc(100% + 4em);border-top:solid rgba(170,170,170,.2666666667) 1px;border-bottom:solid rgba(170,170,170,.2666666667) 1px;z-index:2;background-color:rgba(170,170,170,.1333333333)}code.sourceCode .code-annotation-anchor.code-annotation-active{background-color:var(--quarto-hl-normal-color, #aaaaaa);border:solid var(--quarto-hl-normal-color, #aaaaaa) 1px;color:#e9ecef;font-weight:bolder}code.sourceCode .code-annotation-anchor{font-family:var(--bs-font-monospace);color:var(--quarto-hl-co-color);border:solid var(--quarto-hl-co-color) 1px;border-radius:50%;height:18px;width:18px;font-size:9px;margin-top:2px}code.sourceCode button.code-annotation-anchor{padding:2px}code.sourceCode a.code-annotation-anchor{line-height:18px;text-align:center;vertical-align:middle;cursor:default;text-decoration:none}@media print{.page-columns .column-screen-inset{grid-column:page-start-inset/page-end-inset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-inset table{background:#fff}.page-columns .column-screen-inset-left{grid-column:page-start-inset/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-inset-left table{background:#fff}.page-columns .column-screen-inset-right{grid-column:body-content-start/page-end-inset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-inset-right table{background:#fff}.page-columns .column-screen{grid-column:page-start/page-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen table{background:#fff}.page-columns .column-screen-left{grid-column:page-start/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-left table{background:#fff}.page-columns .column-screen-right{grid-column:body-content-start/page-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-right table{background:#fff}.page-columns .column-screen-inset-shaded{grid-column:page-start-inset/page-end-inset;padding:1em;background:#f8f9fa;z-index:998;transform:translate3d(0, 0, 0);margin-bottom:1em}}.quarto-video{margin-bottom:1em}.table>thead{border-top-width:0}.table>:not(caption)>*:not(:last-child)>*{border-bottom-color:#ebeced;border-bottom-style:solid;border-bottom-width:1px}.table>:not(:first-child){border-top:1px solid #b6babc;border-bottom:1px solid inherit}.table tbody{border-bottom-color:#b6babc}a.external:after{display:inline-block;height:.75rem;width:.75rem;margin-bottom:.15em;margin-left:.25em;content:"";vertical-align:-0.125em;background-image:url('data:image/svg+xml,');background-repeat:no-repeat;background-size:.75rem .75rem}div.sourceCode code a.external:after{content:none}a.external:after:hover{cursor:pointer}.quarto-ext-icon{display:inline-block;font-size:.75em;padding-left:.3em}.code-with-filename .code-with-filename-file{margin-bottom:0;padding-bottom:2px;padding-top:2px;padding-left:.7em;border:var(--quarto-border-width) solid var(--quarto-border-color);border-radius:var(--quarto-border-radius);border-bottom:0;border-bottom-left-radius:0%;border-bottom-right-radius:0%}.code-with-filename div.sourceCode,.reveal .code-with-filename div.sourceCode{margin-top:0;border-top-left-radius:0%;border-top-right-radius:0%}.code-with-filename .code-with-filename-file pre{margin-bottom:0}.code-with-filename .code-with-filename-file,.code-with-filename .code-with-filename-file pre{background-color:rgba(219,219,219,.8)}.quarto-dark .code-with-filename .code-with-filename-file,.quarto-dark .code-with-filename .code-with-filename-file pre{background-color:#555}.code-with-filename .code-with-filename-file strong{font-weight:400}.quarto-title-banner{margin-bottom:1em;color:#545555;background:#f8f9fa}.quarto-title-banner .code-tools-button{color:#878888}.quarto-title-banner .code-tools-button:hover{color:#545555}.quarto-title-banner .code-tools-button>.bi::before{background-image:url('data:image/svg+xml,')}.quarto-title-banner .code-tools-button:hover>.bi::before{background-image:url('data:image/svg+xml,')}.quarto-title-banner .quarto-title .title{font-weight:600}.quarto-title-banner .quarto-categories{margin-top:.75em}@media(min-width: 992px){.quarto-title-banner{padding-top:2.5em;padding-bottom:2.5em}}@media(max-width: 991.98px){.quarto-title-banner{padding-top:1em;padding-bottom:1em}}main.quarto-banner-title-block>section:first-child>h2,main.quarto-banner-title-block>section:first-child>.h2,main.quarto-banner-title-block>section:first-child>h3,main.quarto-banner-title-block>section:first-child>.h3,main.quarto-banner-title-block>section:first-child>h4,main.quarto-banner-title-block>section:first-child>.h4{margin-top:0}.quarto-title .quarto-categories{display:flex;flex-wrap:wrap;row-gap:.5em;column-gap:.4em;padding-bottom:.5em;margin-top:.75em}.quarto-title .quarto-categories .quarto-category{padding:.25em .75em;font-size:.65em;text-transform:uppercase;border:solid 1px;border-radius:.25rem;opacity:.6}.quarto-title .quarto-categories .quarto-category a{color:inherit}#title-block-header.quarto-title-block.default .quarto-title-meta{display:grid;grid-template-columns:repeat(2, 1fr)}#title-block-header.quarto-title-block.default .quarto-title .title{margin-bottom:0}#title-block-header.quarto-title-block.default .quarto-title-author-orcid img{margin-top:-5px}#title-block-header.quarto-title-block.default .quarto-description p:last-of-type{margin-bottom:0}#title-block-header.quarto-title-block.default .quarto-title-meta-contents p,#title-block-header.quarto-title-block.default .quarto-title-authors p,#title-block-header.quarto-title-block.default .quarto-title-affiliations p{margin-bottom:.1em}#title-block-header.quarto-title-block.default .quarto-title-meta-heading{text-transform:uppercase;margin-top:1em;font-size:.8em;opacity:.8;font-weight:400}#title-block-header.quarto-title-block.default .quarto-title-meta-contents{font-size:.9em}#title-block-header.quarto-title-block.default .quarto-title-meta-contents a{color:#373a3c}#title-block-header.quarto-title-block.default .quarto-title-meta-contents p.affiliation:last-of-type{margin-bottom:.7em}#title-block-header.quarto-title-block.default p.affiliation{margin-bottom:.1em}#title-block-header.quarto-title-block.default .description,#title-block-header.quarto-title-block.default .abstract{margin-top:0}#title-block-header.quarto-title-block.default .description>p,#title-block-header.quarto-title-block.default .abstract>p{font-size:.9em}#title-block-header.quarto-title-block.default .description>p:last-of-type,#title-block-header.quarto-title-block.default .abstract>p:last-of-type{margin-bottom:0}#title-block-header.quarto-title-block.default .description .abstract-title,#title-block-header.quarto-title-block.default .abstract .abstract-title{margin-top:1em;text-transform:uppercase;font-size:.8em;opacity:.8;font-weight:400}#title-block-header.quarto-title-block.default .quarto-title-meta-author{display:grid;grid-template-columns:1fr 1fr}.quarto-title-tools-only{display:flex;justify-content:right}body{-webkit-font-smoothing:antialiased}.badge.bg-light{color:#373a3c}.progress .progress-bar{font-size:8px;line-height:8px}/*# sourceMappingURL=038018dfc50d695214e8253e62c2ede5.css.map */ diff --git a/public/site_libs/bootstrap/bootstrap.min.js b/public/site_libs/bootstrap/bootstrap.min.js new file mode 100644 index 00000000..cc0a2556 --- /dev/null +++ b/public/site_libs/bootstrap/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v5.1.3 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t="transitionend",e=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return e},i=t=>{const i=e(t);return i&&document.querySelector(i)?i:null},n=t=>{const i=e(t);return i?document.querySelector(i):null},s=e=>{e.dispatchEvent(new Event(t))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(t):null,a=(t,e,i)=>{Object.keys(i).forEach((n=>{const s=i[n],r=e[n],a=r&&o(r)?"element":null==(l=r)?`${l}`:{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase();var l;if(!new RegExp(s).test(a))throw new TypeError(`${t.toUpperCase()}: Option "${n}" provided type "${a}" but expected type "${s}".`)}))},l=t=>!(!o(t)||0===t.getClientRects().length)&&"visible"===getComputedStyle(t).getPropertyValue("visibility"),c=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),h=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?h(t.parentNode):null},d=()=>{},u=t=>{t.offsetHeight},f=()=>{const{jQuery:t}=window;return t&&!document.body.hasAttribute("data-bs-no-jquery")?t:null},p=[],m=()=>"rtl"===document.documentElement.dir,g=t=>{var e;e=()=>{const e=f();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(p.length||document.addEventListener("DOMContentLoaded",(()=>{p.forEach((t=>t()))})),p.push(e)):e()},_=t=>{"function"==typeof t&&t()},b=(e,i,n=!0)=>{if(!n)return void _(e);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(i)+5;let r=!1;const a=({target:n})=>{n===i&&(r=!0,i.removeEventListener(t,a),_(e))};i.addEventListener(t,a),setTimeout((()=>{r||s(i)}),o)},v=(t,e,i,n)=>{let s=t.indexOf(e);if(-1===s)return t[!i&&n?t.length-1:0];const o=t.length;return s+=i?1:-1,n&&(s=(s+o)%o),t[Math.max(0,Math.min(s,o-1))]},y=/[^.]*(?=\..*)\.|.*/,w=/\..*/,E=/::\d+$/,A={};let T=1;const O={mouseenter:"mouseover",mouseleave:"mouseout"},C=/^(mouseenter|mouseleave)/i,k=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function L(t,e){return e&&`${e}::${T++}`||t.uidEvent||T++}function x(t){const e=L(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function D(t,e,i=null){const n=Object.keys(t);for(let s=0,o=n.length;sfunction(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};n?n=t(n):i=t(i)}const[o,r,a]=S(e,i,n),l=x(t),c=l[a]||(l[a]={}),h=D(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=L(r,e.replace(y,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(let a=o.length;a--;)if(o[a]===r)return s.delegateTarget=r,n.oneOff&&j.off(t,s.type,e,i),i.apply(r,[s]);return null}}(t,i,n):function(t,e){return function i(n){return n.delegateTarget=t,i.oneOff&&j.off(t,n.type,e),e.apply(t,[n])}}(t,i);u.delegationSelector=o?i:null,u.originalHandler=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function I(t,e,i,n,s){const o=D(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function P(t){return t=t.replace(w,""),O[t]||t}const j={on(t,e,i,n){N(t,e,i,n,!1)},one(t,e,i,n){N(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=S(e,i,n),a=r!==e,l=x(t),c=e.startsWith(".");if(void 0!==o){if(!l||!l[r])return;return void I(t,l,r,o,s?i:null)}c&&Object.keys(l).forEach((i=>{!function(t,e,i,n){const s=e[i]||{};Object.keys(s).forEach((o=>{if(o.includes(n)){const n=s[o];I(t,e,i,n.originalHandler,n.delegationSelector)}}))}(t,l,i,e.slice(1))}));const h=l[r]||{};Object.keys(h).forEach((i=>{const n=i.replace(E,"");if(!a||e.includes(n)){const e=h[i];I(t,l,r,e.originalHandler,e.delegationSelector)}}))},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=f(),s=P(e),o=e!==s,r=k.has(s);let a,l=!0,c=!0,h=!1,d=null;return o&&n&&(a=n.Event(e,i),n(t).trigger(a),l=!a.isPropagationStopped(),c=!a.isImmediatePropagationStopped(),h=a.isDefaultPrevented()),r?(d=document.createEvent("HTMLEvents"),d.initEvent(s,l,!0)):d=new CustomEvent(e,{bubbles:l,cancelable:!0}),void 0!==i&&Object.keys(i).forEach((t=>{Object.defineProperty(d,t,{get:()=>i[t]})})),h&&d.preventDefault(),c&&t.dispatchEvent(d),d.defaultPrevented&&void 0!==a&&a.preventDefault(),d}},M=new Map,H={set(t,e,i){M.has(t)||M.set(t,new Map);const n=M.get(t);n.has(e)||0===n.size?n.set(e,i):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(n.keys())[0]}.`)},get:(t,e)=>M.has(t)&&M.get(t).get(e)||null,remove(t,e){if(!M.has(t))return;const i=M.get(t);i.delete(e),0===i.size&&M.delete(t)}};class B{constructor(t){(t=r(t))&&(this._element=t,H.set(this._element,this.constructor.DATA_KEY,this))}dispose(){H.remove(this._element,this.constructor.DATA_KEY),j.off(this._element,this.constructor.EVENT_KEY),Object.getOwnPropertyNames(this).forEach((t=>{this[t]=null}))}_queueCallback(t,e,i=!0){b(t,e,i)}static getInstance(t){return H.get(r(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.1.3"}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}}const R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,s=t.NAME;j.on(document,i,`[data-bs-dismiss="${s}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),c(this))return;const o=n(this)||this.closest(`.${s}`);t.getOrCreateInstance(o)[e]()}))};class W extends B{static get NAME(){return"alert"}close(){if(j.trigger(this._element,"close.bs.alert").defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),j.trigger(this._element,"closed.bs.alert"),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=W.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(W,"close"),g(W);const $='[data-bs-toggle="button"]';class z extends B{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=z.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}function q(t){return"true"===t||"false"!==t&&(t===Number(t).toString()?Number(t):""===t||"null"===t?null:t)}function F(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}j.on(document,"click.bs.button.data-api",$,(t=>{t.preventDefault();const e=t.target.closest($);z.getOrCreateInstance(e).toggle()})),g(z);const U={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${F(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${F(e)}`)},getDataAttributes(t){if(!t)return{};const e={};return Object.keys(t.dataset).filter((t=>t.startsWith("bs"))).forEach((i=>{let n=i.replace(/^bs/,"");n=n.charAt(0).toLowerCase()+n.slice(1,n.length),e[n]=q(t.dataset[i])})),e},getDataAttribute:(t,e)=>q(t.getAttribute(`data-bs-${F(e)}`)),offset(t){const e=t.getBoundingClientRect();return{top:e.top+window.pageYOffset,left:e.left+window.pageXOffset}},position:t=>({top:t.offsetTop,left:t.offsetLeft})},V={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode;for(;n&&n.nodeType===Node.ELEMENT_NODE&&3!==n.nodeType;)n.matches(e)&&i.push(n),n=n.parentNode;return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(", ");return this.find(e,t).filter((t=>!c(t)&&l(t)))}},K="carousel",X={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},Y={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},Q="next",G="prev",Z="left",J="right",tt={ArrowLeft:J,ArrowRight:Z},et="slid.bs.carousel",it="active",nt=".active.carousel-item";class st extends B{constructor(t,e){super(t),this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._indicatorsElement=V.findOne(".carousel-indicators",this._element),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent),this._addEventListeners()}static get Default(){return X}static get NAME(){return K}next(){this._slide(Q)}nextWhenVisible(){!document.hidden&&l(this._element)&&this.next()}prev(){this._slide(G)}pause(t){t||(this._isPaused=!0),V.findOne(".carousel-item-next, .carousel-item-prev",this._element)&&(s(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null}cycle(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config&&this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))}to(t){this._activeElement=V.findOne(nt,this._element);const e=this._getItemIndex(this._activeElement);if(t>this._items.length-1||t<0)return;if(this._isSliding)return void j.one(this._element,et,(()=>this.to(t)));if(e===t)return this.pause(),void this.cycle();const i=t>e?Q:G;this._slide(i,this._items[t])}_getConfig(t){return t={...X,...U.getDataAttributes(this._element),..."object"==typeof t?t:{}},a(K,t,Y),t}_handleSwipe(){const t=Math.abs(this.touchDeltaX);if(t<=40)return;const e=t/this.touchDeltaX;this.touchDeltaX=0,e&&this._slide(e>0?J:Z)}_addEventListeners(){this._config.keyboard&&j.on(this._element,"keydown.bs.carousel",(t=>this._keydown(t))),"hover"===this._config.pause&&(j.on(this._element,"mouseenter.bs.carousel",(t=>this.pause(t))),j.on(this._element,"mouseleave.bs.carousel",(t=>this.cycle(t)))),this._config.touch&&this._touchSupported&&this._addTouchEventListeners()}_addTouchEventListeners(){const t=t=>this._pointerEvent&&("pen"===t.pointerType||"touch"===t.pointerType),e=e=>{t(e)?this.touchStartX=e.clientX:this._pointerEvent||(this.touchStartX=e.touches[0].clientX)},i=t=>{this.touchDeltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this.touchStartX},n=e=>{t(e)&&(this.touchDeltaX=e.clientX-this.touchStartX),this._handleSwipe(),"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((t=>this.cycle(t)),500+this._config.interval))};V.find(".carousel-item img",this._element).forEach((t=>{j.on(t,"dragstart.bs.carousel",(t=>t.preventDefault()))})),this._pointerEvent?(j.on(this._element,"pointerdown.bs.carousel",(t=>e(t))),j.on(this._element,"pointerup.bs.carousel",(t=>n(t))),this._element.classList.add("pointer-event")):(j.on(this._element,"touchstart.bs.carousel",(t=>e(t))),j.on(this._element,"touchmove.bs.carousel",(t=>i(t))),j.on(this._element,"touchend.bs.carousel",(t=>n(t))))}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=tt[t.key];e&&(t.preventDefault(),this._slide(e))}_getItemIndex(t){return this._items=t&&t.parentNode?V.find(".carousel-item",t.parentNode):[],this._items.indexOf(t)}_getItemByOrder(t,e){const i=t===Q;return v(this._items,e,i,this._config.wrap)}_triggerSlideEvent(t,e){const i=this._getItemIndex(t),n=this._getItemIndex(V.findOne(nt,this._element));return j.trigger(this._element,"slide.bs.carousel",{relatedTarget:t,direction:e,from:n,to:i})}_setActiveIndicatorElement(t){if(this._indicatorsElement){const e=V.findOne(".active",this._indicatorsElement);e.classList.remove(it),e.removeAttribute("aria-current");const i=V.find("[data-bs-target]",this._indicatorsElement);for(let e=0;e{j.trigger(this._element,et,{relatedTarget:o,direction:d,from:s,to:r})};if(this._element.classList.contains("slide")){o.classList.add(h),u(o),n.classList.add(c),o.classList.add(c);const t=()=>{o.classList.remove(c,h),o.classList.add(it),n.classList.remove(it,h,c),this._isSliding=!1,setTimeout(f,0)};this._queueCallback(t,n,!0)}else n.classList.remove(it),o.classList.add(it),this._isSliding=!1,f();a&&this.cycle()}_directionToOrder(t){return[J,Z].includes(t)?m()?t===Z?G:Q:t===Z?Q:G:t}_orderToDirection(t){return[Q,G].includes(t)?m()?t===G?Z:J:t===G?J:Z:t}static carouselInterface(t,e){const i=st.getOrCreateInstance(t,e);let{_config:n}=i;"object"==typeof e&&(n={...n,...e});const s="string"==typeof e?e:n.slide;if("number"==typeof e)i.to(e);else if("string"==typeof s){if(void 0===i[s])throw new TypeError(`No method named "${s}"`);i[s]()}else n.interval&&n.ride&&(i.pause(),i.cycle())}static jQueryInterface(t){return this.each((function(){st.carouselInterface(this,t)}))}static dataApiClickHandler(t){const e=n(this);if(!e||!e.classList.contains("carousel"))return;const i={...U.getDataAttributes(e),...U.getDataAttributes(this)},s=this.getAttribute("data-bs-slide-to");s&&(i.interval=!1),st.carouselInterface(e,i),s&&st.getInstance(e).to(s),t.preventDefault()}}j.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",st.dataApiClickHandler),j.on(window,"load.bs.carousel.data-api",(()=>{const t=V.find('[data-bs-ride="carousel"]');for(let e=0,i=t.length;et===this._element));null!==s&&o.length&&(this._selector=s,this._triggerArray.push(e))}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return rt}static get NAME(){return ot}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t,e=[];if(this._config.parent){const t=V.find(ut,this._config.parent);e=V.find(".collapse.show, .collapse.collapsing",this._config.parent).filter((e=>!t.includes(e)))}const i=V.findOne(this._selector);if(e.length){const n=e.find((t=>i!==t));if(t=n?pt.getInstance(n):null,t&&t._isTransitioning)return}if(j.trigger(this._element,"show.bs.collapse").defaultPrevented)return;e.forEach((e=>{i!==e&&pt.getOrCreateInstance(e,{toggle:!1}).hide(),t||H.set(e,"bs.collapse",null)}));const n=this._getDimension();this._element.classList.remove(ct),this._element.classList.add(ht),this._element.style[n]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const s=`scroll${n[0].toUpperCase()+n.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ht),this._element.classList.add(ct,lt),this._element.style[n]="",j.trigger(this._element,"shown.bs.collapse")}),this._element,!0),this._element.style[n]=`${this._element[s]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(j.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,u(this._element),this._element.classList.add(ht),this._element.classList.remove(ct,lt);const e=this._triggerArray.length;for(let t=0;t{this._isTransitioning=!1,this._element.classList.remove(ht),this._element.classList.add(ct),j.trigger(this._element,"hidden.bs.collapse")}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(lt)}_getConfig(t){return(t={...rt,...U.getDataAttributes(this._element),...t}).toggle=Boolean(t.toggle),t.parent=r(t.parent),a(ot,t,at),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=V.find(ut,this._config.parent);V.find(ft,this._config.parent).filter((e=>!t.includes(e))).forEach((t=>{const e=n(t);e&&this._addAriaAndCollapsedClass([t],this._isShown(e))}))}_addAriaAndCollapsedClass(t,e){t.length&&t.forEach((t=>{e?t.classList.remove(dt):t.classList.add(dt),t.setAttribute("aria-expanded",e)}))}static jQueryInterface(t){return this.each((function(){const e={};"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1);const i=pt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}j.on(document,"click.bs.collapse.data-api",ft,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();const e=i(this);V.find(e).forEach((t=>{pt.getOrCreateInstance(t,{toggle:!1}).toggle()}))})),g(pt);var mt="top",gt="bottom",_t="right",bt="left",vt="auto",yt=[mt,gt,_t,bt],wt="start",Et="end",At="clippingParents",Tt="viewport",Ot="popper",Ct="reference",kt=yt.reduce((function(t,e){return t.concat([e+"-"+wt,e+"-"+Et])}),[]),Lt=[].concat(yt,[vt]).reduce((function(t,e){return t.concat([e,e+"-"+wt,e+"-"+Et])}),[]),xt="beforeRead",Dt="read",St="afterRead",Nt="beforeMain",It="main",Pt="afterMain",jt="beforeWrite",Mt="write",Ht="afterWrite",Bt=[xt,Dt,St,Nt,It,Pt,jt,Mt,Ht];function Rt(t){return t?(t.nodeName||"").toLowerCase():null}function Wt(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function $t(t){return t instanceof Wt(t).Element||t instanceof Element}function zt(t){return t instanceof Wt(t).HTMLElement||t instanceof HTMLElement}function qt(t){return"undefined"!=typeof ShadowRoot&&(t instanceof Wt(t).ShadowRoot||t instanceof ShadowRoot)}const Ft={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];zt(s)&&Rt(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});zt(n)&&Rt(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function Ut(t){return t.split("-")[0]}function Vt(t,e){var i=t.getBoundingClientRect();return{width:i.width/1,height:i.height/1,top:i.top/1,right:i.right/1,bottom:i.bottom/1,left:i.left/1,x:i.left/1,y:i.top/1}}function Kt(t){var e=Vt(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function Xt(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&qt(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function Yt(t){return Wt(t).getComputedStyle(t)}function Qt(t){return["table","td","th"].indexOf(Rt(t))>=0}function Gt(t){return(($t(t)?t.ownerDocument:t.document)||window.document).documentElement}function Zt(t){return"html"===Rt(t)?t:t.assignedSlot||t.parentNode||(qt(t)?t.host:null)||Gt(t)}function Jt(t){return zt(t)&&"fixed"!==Yt(t).position?t.offsetParent:null}function te(t){for(var e=Wt(t),i=Jt(t);i&&Qt(i)&&"static"===Yt(i).position;)i=Jt(i);return i&&("html"===Rt(i)||"body"===Rt(i)&&"static"===Yt(i).position)?e:i||function(t){var e=-1!==navigator.userAgent.toLowerCase().indexOf("firefox");if(-1!==navigator.userAgent.indexOf("Trident")&&zt(t)&&"fixed"===Yt(t).position)return null;for(var i=Zt(t);zt(i)&&["html","body"].indexOf(Rt(i))<0;){var n=Yt(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function ee(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}var ie=Math.max,ne=Math.min,se=Math.round;function oe(t,e,i){return ie(t,ne(e,i))}function re(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function ae(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const le={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=Ut(i.placement),l=ee(a),c=[bt,_t].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return re("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:ae(t,yt))}(s.padding,i),d=Kt(o),u="y"===l?mt:bt,f="y"===l?gt:_t,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=te(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,E=oe(v,w,y),A=l;i.modifiersData[n]=((e={})[A]=E,e.centerOffset=E-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&Xt(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function ce(t){return t.split("-")[1]}var he={top:"auto",right:"auto",bottom:"auto",left:"auto"};function de(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=!0===h?function(t){var e=t.x,i=t.y,n=window.devicePixelRatio||1;return{x:se(se(e*n)/n)||0,y:se(se(i*n)/n)||0}}(r):"function"==typeof h?h(r):r,u=d.x,f=void 0===u?0:u,p=d.y,m=void 0===p?0:p,g=r.hasOwnProperty("x"),_=r.hasOwnProperty("y"),b=bt,v=mt,y=window;if(c){var w=te(i),E="clientHeight",A="clientWidth";w===Wt(i)&&"static"!==Yt(w=Gt(i)).position&&"absolute"===a&&(E="scrollHeight",A="scrollWidth"),w=w,s!==mt&&(s!==bt&&s!==_t||o!==Et)||(v=gt,m-=w[E]-n.height,m*=l?1:-1),s!==bt&&(s!==mt&&s!==gt||o!==Et)||(b=_t,f-=w[A]-n.width,f*=l?1:-1)}var T,O=Object.assign({position:a},c&&he);return l?Object.assign({},O,((T={})[v]=_?"0":"",T[b]=g?"0":"",T.transform=(y.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",T)):Object.assign({},O,((e={})[v]=_?m+"px":"",e[b]=g?f+"px":"",e.transform="",e))}const ue={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:Ut(e.placement),variation:ce(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,de(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,de(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var fe={passive:!0};const pe={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=Wt(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,fe)})),a&&l.addEventListener("resize",i.update,fe),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,fe)})),a&&l.removeEventListener("resize",i.update,fe)}},data:{}};var me={left:"right",right:"left",bottom:"top",top:"bottom"};function ge(t){return t.replace(/left|right|bottom|top/g,(function(t){return me[t]}))}var _e={start:"end",end:"start"};function be(t){return t.replace(/start|end/g,(function(t){return _e[t]}))}function ve(t){var e=Wt(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function ye(t){return Vt(Gt(t)).left+ve(t).scrollLeft}function we(t){var e=Yt(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ee(t){return["html","body","#document"].indexOf(Rt(t))>=0?t.ownerDocument.body:zt(t)&&we(t)?t:Ee(Zt(t))}function Ae(t,e){var i;void 0===e&&(e=[]);var n=Ee(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=Wt(n),r=s?[o].concat(o.visualViewport||[],we(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(Ae(Zt(r)))}function Te(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function Oe(t,e){return e===Tt?Te(function(t){var e=Wt(t),i=Gt(t),n=e.visualViewport,s=i.clientWidth,o=i.clientHeight,r=0,a=0;return n&&(s=n.width,o=n.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(r=n.offsetLeft,a=n.offsetTop)),{width:s,height:o,x:r+ye(t),y:a}}(t)):zt(e)?function(t){var e=Vt(t);return e.top=e.top+t.clientTop,e.left=e.left+t.clientLeft,e.bottom=e.top+t.clientHeight,e.right=e.left+t.clientWidth,e.width=t.clientWidth,e.height=t.clientHeight,e.x=e.left,e.y=e.top,e}(e):Te(function(t){var e,i=Gt(t),n=ve(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=ie(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=ie(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+ye(t),l=-n.scrollTop;return"rtl"===Yt(s||i).direction&&(a+=ie(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(Gt(t)))}function Ce(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?Ut(s):null,r=s?ce(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case mt:e={x:a,y:i.y-n.height};break;case gt:e={x:a,y:i.y+i.height};break;case _t:e={x:i.x+i.width,y:l};break;case bt:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?ee(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case wt:e[c]=e[c]-(i[h]/2-n[h]/2);break;case Et:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function ke(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.boundary,r=void 0===o?At:o,a=i.rootBoundary,l=void 0===a?Tt:a,c=i.elementContext,h=void 0===c?Ot:c,d=i.altBoundary,u=void 0!==d&&d,f=i.padding,p=void 0===f?0:f,m=re("number"!=typeof p?p:ae(p,yt)),g=h===Ot?Ct:Ot,_=t.rects.popper,b=t.elements[u?g:h],v=function(t,e,i){var n="clippingParents"===e?function(t){var e=Ae(Zt(t)),i=["absolute","fixed"].indexOf(Yt(t).position)>=0&&zt(t)?te(t):t;return $t(i)?e.filter((function(t){return $t(t)&&Xt(t,i)&&"body"!==Rt(t)})):[]}(t):[].concat(e),s=[].concat(n,[i]),o=s[0],r=s.reduce((function(e,i){var n=Oe(t,i);return e.top=ie(n.top,e.top),e.right=ne(n.right,e.right),e.bottom=ne(n.bottom,e.bottom),e.left=ie(n.left,e.left),e}),Oe(t,o));return r.width=r.right-r.left,r.height=r.bottom-r.top,r.x=r.left,r.y=r.top,r}($t(b)?b:b.contextElement||Gt(t.elements.popper),r,l),y=Vt(t.elements.reference),w=Ce({reference:y,element:_,strategy:"absolute",placement:s}),E=Te(Object.assign({},_,w)),A=h===Ot?E:y,T={top:v.top-A.top+m.top,bottom:A.bottom-v.bottom+m.bottom,left:v.left-A.left+m.left,right:A.right-v.right+m.right},O=t.modifiersData.offset;if(h===Ot&&O){var C=O[s];Object.keys(T).forEach((function(t){var e=[_t,gt].indexOf(t)>=0?1:-1,i=[mt,gt].indexOf(t)>=0?"y":"x";T[t]+=C[i]*e}))}return T}function Le(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?Lt:l,h=ce(n),d=h?a?kt:kt.filter((function(t){return ce(t)===h})):yt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=ke(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[Ut(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const xe={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=Ut(g),b=l||(_!==g&&p?function(t){if(Ut(t)===vt)return[];var e=ge(t);return[be(t),e,be(e)]}(g):[ge(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(Ut(i)===vt?Le(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,E=new Map,A=!0,T=v[0],O=0;O=0,D=x?"width":"height",S=ke(e,{placement:C,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),N=x?L?_t:bt:L?gt:mt;y[D]>w[D]&&(N=ge(N));var I=ge(N),P=[];if(o&&P.push(S[k]<=0),a&&P.push(S[N]<=0,S[I]<=0),P.every((function(t){return t}))){T=C,A=!1;break}E.set(C,P)}if(A)for(var j=function(t){var e=v.find((function(e){var i=E.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},M=p?3:1;M>0&&"break"!==j(M);M--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function De(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function Se(t){return[mt,_t,gt,bt].some((function(e){return t[e]>=0}))}const Ne={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=ke(e,{elementContext:"reference"}),a=ke(e,{altBoundary:!0}),l=De(r,n),c=De(a,s,o),h=Se(l),d=Se(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},Ie={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=Lt.reduce((function(t,i){return t[i]=function(t,e,i){var n=Ut(t),s=[bt,mt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[bt,_t].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},Pe={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=Ce({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},je={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=ke(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=Ut(e.placement),b=ce(e.placement),v=!b,y=ee(_),w="x"===y?"y":"x",E=e.modifiersData.popperOffsets,A=e.rects.reference,T=e.rects.popper,O="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,C={x:0,y:0};if(E){if(o||a){var k="y"===y?mt:bt,L="y"===y?gt:_t,x="y"===y?"height":"width",D=E[y],S=E[y]+g[k],N=E[y]-g[L],I=f?-T[x]/2:0,P=b===wt?A[x]:T[x],j=b===wt?-T[x]:-A[x],M=e.elements.arrow,H=f&&M?Kt(M):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},R=B[k],W=B[L],$=oe(0,A[x],H[x]),z=v?A[x]/2-I-$-R-O:P-$-R-O,q=v?-A[x]/2+I+$+W+O:j+$+W+O,F=e.elements.arrow&&te(e.elements.arrow),U=F?"y"===y?F.clientTop||0:F.clientLeft||0:0,V=e.modifiersData.offset?e.modifiersData.offset[e.placement][y]:0,K=E[y]+z-V-U,X=E[y]+q-V;if(o){var Y=oe(f?ne(S,K):S,D,f?ie(N,X):N);E[y]=Y,C[y]=Y-D}if(a){var Q="x"===y?mt:bt,G="x"===y?gt:_t,Z=E[w],J=Z+g[Q],tt=Z-g[G],et=oe(f?ne(J,K):J,Z,f?ie(tt,X):tt);E[w]=et,C[w]=et-Z}}e.modifiersData[n]=C}},requiresIfExists:["offset"]};function Me(t,e,i){void 0===i&&(i=!1);var n=zt(e);zt(e)&&function(t){var e=t.getBoundingClientRect();e.width,t.offsetWidth,e.height,t.offsetHeight}(e);var s,o,r=Gt(e),a=Vt(t),l={scrollLeft:0,scrollTop:0},c={x:0,y:0};return(n||!n&&!i)&&(("body"!==Rt(e)||we(r))&&(l=(s=e)!==Wt(s)&&zt(s)?{scrollLeft:(o=s).scrollLeft,scrollTop:o.scrollTop}:ve(s)),zt(e)?((c=Vt(e)).x+=e.clientLeft,c.y+=e.clientTop):r&&(c.x=ye(r))),{x:a.left+l.scrollLeft-c.x,y:a.top+l.scrollTop-c.y,width:a.width,height:a.height}}function He(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var Be={placement:"bottom",modifiers:[],strategy:"absolute"};function Re(){for(var t=arguments.length,e=new Array(t),i=0;ij.on(t,"mouseover",d))),this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.add(Je),this._element.classList.add(Je),j.trigger(this._element,"shown.bs.dropdown",t)}hide(){if(c(this._element)||!this._isShown(this._menu))return;const t={relatedTarget:this._element};this._completeHide(t)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_completeHide(t){j.trigger(this._element,"hide.bs.dropdown",t).defaultPrevented||("ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((t=>j.off(t,"mouseover",d))),this._popper&&this._popper.destroy(),this._menu.classList.remove(Je),this._element.classList.remove(Je),this._element.setAttribute("aria-expanded","false"),U.removeDataAttribute(this._menu,"popper"),j.trigger(this._element,"hidden.bs.dropdown",t))}_getConfig(t){if(t={...this.constructor.Default,...U.getDataAttributes(this._element),...t},a(Ue,t,this.constructor.DefaultType),"object"==typeof t.reference&&!o(t.reference)&&"function"!=typeof t.reference.getBoundingClientRect)throw new TypeError(`${Ue.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);return t}_createPopper(t){if(void 0===Fe)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");let e=this._element;"parent"===this._config.reference?e=t:o(this._config.reference)?e=r(this._config.reference):"object"==typeof this._config.reference&&(e=this._config.reference);const i=this._getPopperConfig(),n=i.modifiers.find((t=>"applyStyles"===t.name&&!1===t.enabled));this._popper=qe(e,this._menu,i),n&&U.setDataAttribute(this._menu,"popper","static")}_isShown(t=this._element){return t.classList.contains(Je)}_getMenuElement(){return V.next(this._element,ei)[0]}_getPlacement(){const t=this._element.parentNode;if(t.classList.contains("dropend"))return ri;if(t.classList.contains("dropstart"))return ai;const e="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return t.classList.contains("dropup")?e?ni:ii:e?oi:si}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return"static"===this._config.display&&(t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,..."function"==typeof this._config.popperConfig?this._config.popperConfig(t):this._config.popperConfig}}_selectMenuItem({key:t,target:e}){const i=V.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter(l);i.length&&v(i,e,t===Ye,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=hi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(t&&(2===t.button||"keyup"===t.type&&"Tab"!==t.key))return;const e=V.find(ti);for(let i=0,n=e.length;ie+t)),this._setElementAttributes(di,"paddingRight",(e=>e+t)),this._setElementAttributes(ui,"marginRight",(e=>e-t))}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t)[e];t.style[e]=`${i(Number.parseFloat(s))}px`}))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,"paddingRight"),this._resetElementAttributes(di,"paddingRight"),this._resetElementAttributes(ui,"marginRight")}_saveInitialAttribute(t,e){const i=t.style[e];i&&U.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=U.getDataAttribute(t,e);void 0===i?t.style.removeProperty(e):(U.removeDataAttribute(t,e),t.style[e]=i)}))}_applyManipulationCallback(t,e){o(t)?e(t):V.find(t,this._element).forEach(e)}isOverflowing(){return this.getWidth()>0}}const pi={className:"modal-backdrop",isVisible:!0,isAnimated:!1,rootElement:"body",clickCallback:null},mi={className:"string",isVisible:"boolean",isAnimated:"boolean",rootElement:"(element|string)",clickCallback:"(function|null)"},gi="show",_i="mousedown.bs.backdrop";class bi{constructor(t){this._config=this._getConfig(t),this._isAppended=!1,this._element=null}show(t){this._config.isVisible?(this._append(),this._config.isAnimated&&u(this._getElement()),this._getElement().classList.add(gi),this._emulateAnimation((()=>{_(t)}))):_(t)}hide(t){this._config.isVisible?(this._getElement().classList.remove(gi),this._emulateAnimation((()=>{this.dispose(),_(t)}))):_(t)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_getConfig(t){return(t={...pi,..."object"==typeof t?t:{}}).rootElement=r(t.rootElement),a("backdrop",t,mi),t}_append(){this._isAppended||(this._config.rootElement.append(this._getElement()),j.on(this._getElement(),_i,(()=>{_(this._config.clickCallback)})),this._isAppended=!0)}dispose(){this._isAppended&&(j.off(this._element,_i),this._element.remove(),this._isAppended=!1)}_emulateAnimation(t){b(t,this._getElement(),this._config.isAnimated)}}const vi={trapElement:null,autofocus:!0},yi={trapElement:"element",autofocus:"boolean"},wi=".bs.focustrap",Ei="backward";class Ai{constructor(t){this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}activate(){const{trapElement:t,autofocus:e}=this._config;this._isActive||(e&&t.focus(),j.off(document,wi),j.on(document,"focusin.bs.focustrap",(t=>this._handleFocusin(t))),j.on(document,"keydown.tab.bs.focustrap",(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,j.off(document,wi))}_handleFocusin(t){const{target:e}=t,{trapElement:i}=this._config;if(e===document||e===i||i.contains(e))return;const n=V.focusableChildren(i);0===n.length?i.focus():this._lastTabNavDirection===Ei?n[n.length-1].focus():n[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?Ei:"forward")}_getConfig(t){return t={...vi,..."object"==typeof t?t:{}},a("focustrap",t,yi),t}}const Ti="modal",Oi="Escape",Ci={backdrop:!0,keyboard:!0,focus:!0},ki={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean"},Li="hidden.bs.modal",xi="show.bs.modal",Di="resize.bs.modal",Si="click.dismiss.bs.modal",Ni="keydown.dismiss.bs.modal",Ii="mousedown.dismiss.bs.modal",Pi="modal-open",ji="show",Mi="modal-static";class Hi extends B{constructor(t,e){super(t),this._config=this._getConfig(e),this._dialog=V.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollBar=new fi}static get Default(){return Ci}static get NAME(){return Ti}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||j.trigger(this._element,xi,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isAnimated()&&(this._isTransitioning=!0),this._scrollBar.hide(),document.body.classList.add(Pi),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),j.on(this._dialog,Ii,(()=>{j.one(this._element,"mouseup.dismiss.bs.modal",(t=>{t.target===this._element&&(this._ignoreBackdropClick=!0)}))})),this._showBackdrop((()=>this._showElement(t))))}hide(){if(!this._isShown||this._isTransitioning)return;if(j.trigger(this._element,"hide.bs.modal").defaultPrevented)return;this._isShown=!1;const t=this._isAnimated();t&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),this._focustrap.deactivate(),this._element.classList.remove(ji),j.off(this._element,Si),j.off(this._dialog,Ii),this._queueCallback((()=>this._hideModal()),this._element,t)}dispose(){[window,this._dialog].forEach((t=>j.off(t,".bs.modal"))),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new bi({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new Ai({trapElement:this._element})}_getConfig(t){return t={...Ci,...U.getDataAttributes(this._element),..."object"==typeof t?t:{}},a(Ti,t,ki),t}_showElement(t){const e=this._isAnimated(),i=V.findOne(".modal-body",this._dialog);this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0,i&&(i.scrollTop=0),e&&u(this._element),this._element.classList.add(ji),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,j.trigger(this._element,"shown.bs.modal",{relatedTarget:t})}),this._dialog,e)}_setEscapeEvent(){this._isShown?j.on(this._element,Ni,(t=>{this._config.keyboard&&t.key===Oi?(t.preventDefault(),this.hide()):this._config.keyboard||t.key!==Oi||this._triggerBackdropTransition()})):j.off(this._element,Ni)}_setResizeEvent(){this._isShown?j.on(window,Di,(()=>this._adjustDialog())):j.off(window,Di)}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(Pi),this._resetAdjustments(),this._scrollBar.reset(),j.trigger(this._element,Li)}))}_showBackdrop(t){j.on(this._element,Si,(t=>{this._ignoreBackdropClick?this._ignoreBackdropClick=!1:t.target===t.currentTarget&&(!0===this._config.backdrop?this.hide():"static"===this._config.backdrop&&this._triggerBackdropTransition())})),this._backdrop.show(t)}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(j.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const{classList:t,scrollHeight:e,style:i}=this._element,n=e>document.documentElement.clientHeight;!n&&"hidden"===i.overflowY||t.contains(Mi)||(n||(i.overflowY="hidden"),t.add(Mi),this._queueCallback((()=>{t.remove(Mi),n||this._queueCallback((()=>{i.overflowY=""}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;(!i&&t&&!m()||i&&!t&&m())&&(this._element.style.paddingLeft=`${e}px`),(i&&!t&&!m()||!i&&t&&m())&&(this._element.style.paddingRight=`${e}px`)}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=Hi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}j.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(t){const e=n(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),j.one(e,xi,(t=>{t.defaultPrevented||j.one(e,Li,(()=>{l(this)&&this.focus()}))}));const i=V.findOne(".modal.show");i&&Hi.getInstance(i).hide(),Hi.getOrCreateInstance(e).toggle(this)})),R(Hi),g(Hi);const Bi="offcanvas",Ri={backdrop:!0,keyboard:!0,scroll:!1},Wi={backdrop:"boolean",keyboard:"boolean",scroll:"boolean"},$i="show",zi=".offcanvas.show",qi="hidden.bs.offcanvas";class Fi extends B{constructor(t,e){super(t),this._config=this._getConfig(e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get NAME(){return Bi}static get Default(){return Ri}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||j.trigger(this._element,"show.bs.offcanvas",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._element.style.visibility="visible",this._backdrop.show(),this._config.scroll||(new fi).hide(),this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add($i),this._queueCallback((()=>{this._config.scroll||this._focustrap.activate(),j.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(j.trigger(this._element,"hide.bs.offcanvas").defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.remove($i),this._backdrop.hide(),this._queueCallback((()=>{this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._element.style.visibility="hidden",this._config.scroll||(new fi).reset(),j.trigger(this._element,qi)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_getConfig(t){return t={...Ri,...U.getDataAttributes(this._element),..."object"==typeof t?t:{}},a(Bi,t,Wi),t}_initializeBackDrop(){return new bi({className:"offcanvas-backdrop",isVisible:this._config.backdrop,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:()=>this.hide()})}_initializeFocusTrap(){return new Ai({trapElement:this._element})}_addEventListeners(){j.on(this._element,"keydown.dismiss.bs.offcanvas",(t=>{this._config.keyboard&&"Escape"===t.key&&this.hide()}))}static jQueryInterface(t){return this.each((function(){const e=Fi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}j.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(t){const e=n(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),c(this))return;j.one(e,qi,(()=>{l(this)&&this.focus()}));const i=V.findOne(zi);i&&i!==e&&Fi.getInstance(i).hide(),Fi.getOrCreateInstance(e).toggle(this)})),j.on(window,"load.bs.offcanvas.data-api",(()=>V.find(zi).forEach((t=>Fi.getOrCreateInstance(t).show())))),R(Fi),g(Fi);const Ui=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Vi=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i,Ki=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,Xi=(t,e)=>{const i=t.nodeName.toLowerCase();if(e.includes(i))return!Ui.has(i)||Boolean(Vi.test(t.nodeValue)||Ki.test(t.nodeValue));const n=e.filter((t=>t instanceof RegExp));for(let t=0,e=n.length;t{Xi(t,r)||i.removeAttribute(t.nodeName)}))}return n.body.innerHTML}const Qi="tooltip",Gi=new Set(["sanitize","allowList","sanitizeFn"]),Zi={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(array|string|function)",container:"(string|element|boolean)",fallbackPlacements:"array",boundary:"(string|element)",customClass:"(string|function)",sanitize:"boolean",sanitizeFn:"(null|function)",allowList:"object",popperConfig:"(null|object|function)"},Ji={AUTO:"auto",TOP:"top",RIGHT:m()?"left":"right",BOTTOM:"bottom",LEFT:m()?"right":"left"},tn={animation:!0,template:'',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:[0,0],container:!1,fallbackPlacements:["top","right","bottom","left"],boundary:"clippingParents",customClass:"",sanitize:!0,sanitizeFn:null,allowList:{"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},popperConfig:null},en={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},nn="fade",sn="show",on="show",rn="out",an=".tooltip-inner",ln=".modal",cn="hide.bs.modal",hn="hover",dn="focus";class un extends B{constructor(t,e){if(void 0===Fe)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t),this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this._config=this._getConfig(e),this.tip=null,this._setListeners()}static get Default(){return tn}static get NAME(){return Qi}static get Event(){return en}static get DefaultType(){return Zi}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(t){if(this._isEnabled)if(t){const e=this._initializeOnDelegatedTarget(t);e._activeTrigger.click=!e._activeTrigger.click,e._isWithActiveTrigger()?e._enter(null,e):e._leave(null,e)}else{if(this.getTipElement().classList.contains(sn))return void this._leave(null,this);this._enter(null,this)}}dispose(){clearTimeout(this._timeout),j.off(this._element.closest(ln),cn,this._hideModalHandler),this.tip&&this.tip.remove(),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this.isWithContent()||!this._isEnabled)return;const t=j.trigger(this._element,this.constructor.Event.SHOW),e=h(this._element),i=null===e?this._element.ownerDocument.documentElement.contains(this._element):e.contains(this._element);if(t.defaultPrevented||!i)return;"tooltip"===this.constructor.NAME&&this.tip&&this.getTitle()!==this.tip.querySelector(an).innerHTML&&(this._disposePopper(),this.tip.remove(),this.tip=null);const n=this.getTipElement(),s=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME);n.setAttribute("id",s),this._element.setAttribute("aria-describedby",s),this._config.animation&&n.classList.add(nn);const o="function"==typeof this._config.placement?this._config.placement.call(this,n,this._element):this._config.placement,r=this._getAttachment(o);this._addAttachmentClass(r);const{container:a}=this._config;H.set(n,this.constructor.DATA_KEY,this),this._element.ownerDocument.documentElement.contains(this.tip)||(a.append(n),j.trigger(this._element,this.constructor.Event.INSERTED)),this._popper?this._popper.update():this._popper=qe(this._element,n,this._getPopperConfig(r)),n.classList.add(sn);const l=this._resolvePossibleFunction(this._config.customClass);l&&n.classList.add(...l.split(" ")),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((t=>{j.on(t,"mouseover",d)}));const c=this.tip.classList.contains(nn);this._queueCallback((()=>{const t=this._hoverState;this._hoverState=null,j.trigger(this._element,this.constructor.Event.SHOWN),t===rn&&this._leave(null,this)}),this.tip,c)}hide(){if(!this._popper)return;const t=this.getTipElement();if(j.trigger(this._element,this.constructor.Event.HIDE).defaultPrevented)return;t.classList.remove(sn),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((t=>j.off(t,"mouseover",d))),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1;const e=this.tip.classList.contains(nn);this._queueCallback((()=>{this._isWithActiveTrigger()||(this._hoverState!==on&&t.remove(),this._cleanTipClass(),this._element.removeAttribute("aria-describedby"),j.trigger(this._element,this.constructor.Event.HIDDEN),this._disposePopper())}),this.tip,e),this._hoverState=""}update(){null!==this._popper&&this._popper.update()}isWithContent(){return Boolean(this.getTitle())}getTipElement(){if(this.tip)return this.tip;const t=document.createElement("div");t.innerHTML=this._config.template;const e=t.children[0];return this.setContent(e),e.classList.remove(nn,sn),this.tip=e,this.tip}setContent(t){this._sanitizeAndSetContent(t,this.getTitle(),an)}_sanitizeAndSetContent(t,e,i){const n=V.findOne(i,t);e||!n?this.setElementContent(n,e):n.remove()}setElementContent(t,e){if(null!==t)return o(e)?(e=r(e),void(this._config.html?e.parentNode!==t&&(t.innerHTML="",t.append(e)):t.textContent=e.textContent)):void(this._config.html?(this._config.sanitize&&(e=Yi(e,this._config.allowList,this._config.sanitizeFn)),t.innerHTML=e):t.textContent=e)}getTitle(){const t=this._element.getAttribute("data-bs-original-title")||this._config.title;return this._resolvePossibleFunction(t)}updateAttachment(t){return"right"===t?"end":"left"===t?"start":t}_initializeOnDelegatedTarget(t,e){return e||this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return"function"==typeof t?t.call(this._element):t}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"onChange",enabled:!0,phase:"afterWrite",fn:t=>this._handlePopperPlacementChange(t)}],onFirstUpdate:t=>{t.options.placement!==t.placement&&this._handlePopperPlacementChange(t)}};return{...e,..."function"==typeof this._config.popperConfig?this._config.popperConfig(e):this._config.popperConfig}}_addAttachmentClass(t){this.getTipElement().classList.add(`${this._getBasicClassPrefix()}-${this.updateAttachment(t)}`)}_getAttachment(t){return Ji[t.toUpperCase()]}_setListeners(){this._config.trigger.split(" ").forEach((t=>{if("click"===t)j.on(this._element,this.constructor.Event.CLICK,this._config.selector,(t=>this.toggle(t)));else if("manual"!==t){const e=t===hn?this.constructor.Event.MOUSEENTER:this.constructor.Event.FOCUSIN,i=t===hn?this.constructor.Event.MOUSELEAVE:this.constructor.Event.FOCUSOUT;j.on(this._element,e,this._config.selector,(t=>this._enter(t))),j.on(this._element,i,this._config.selector,(t=>this._leave(t)))}})),this._hideModalHandler=()=>{this._element&&this.hide()},j.on(this._element.closest(ln),cn,this._hideModalHandler),this._config.selector?this._config={...this._config,trigger:"manual",selector:""}:this._fixTitle()}_fixTitle(){const t=this._element.getAttribute("title"),e=typeof this._element.getAttribute("data-bs-original-title");(t||"string"!==e)&&(this._element.setAttribute("data-bs-original-title",t||""),!t||this._element.getAttribute("aria-label")||this._element.textContent||this._element.setAttribute("aria-label",t),this._element.setAttribute("title",""))}_enter(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusin"===t.type?dn:hn]=!0),e.getTipElement().classList.contains(sn)||e._hoverState===on?e._hoverState=on:(clearTimeout(e._timeout),e._hoverState=on,e._config.delay&&e._config.delay.show?e._timeout=setTimeout((()=>{e._hoverState===on&&e.show()}),e._config.delay.show):e.show())}_leave(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusout"===t.type?dn:hn]=e._element.contains(t.relatedTarget)),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=rn,e._config.delay&&e._config.delay.hide?e._timeout=setTimeout((()=>{e._hoverState===rn&&e.hide()}),e._config.delay.hide):e.hide())}_isWithActiveTrigger(){for(const t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1}_getConfig(t){const e=U.getDataAttributes(this._element);return Object.keys(e).forEach((t=>{Gi.has(t)&&delete e[t]})),(t={...this.constructor.Default,...e,..."object"==typeof t&&t?t:{}}).container=!1===t.container?document.body:r(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),a(Qi,t,this.constructor.DefaultType),t.sanitize&&(t.template=Yi(t.template,t.allowList,t.sanitizeFn)),t}_getDelegateConfig(){const t={};for(const e in this._config)this.constructor.Default[e]!==this._config[e]&&(t[e]=this._config[e]);return t}_cleanTipClass(){const t=this.getTipElement(),e=new RegExp(`(^|\\s)${this._getBasicClassPrefix()}\\S+`,"g"),i=t.getAttribute("class").match(e);null!==i&&i.length>0&&i.map((t=>t.trim())).forEach((e=>t.classList.remove(e)))}_getBasicClassPrefix(){return"bs-tooltip"}_handlePopperPlacementChange(t){const{state:e}=t;e&&(this.tip=e.elements.popper,this._cleanTipClass(),this._addAttachmentClass(this._getAttachment(e.placement)))}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null)}static jQueryInterface(t){return this.each((function(){const e=un.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}g(un);const fn={...un.Default,placement:"right",offset:[0,8],trigger:"click",content:"",template:''},pn={...un.DefaultType,content:"(string|element|function)"},mn={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"};class gn extends un{static get Default(){return fn}static get NAME(){return"popover"}static get Event(){return mn}static get DefaultType(){return pn}isWithContent(){return this.getTitle()||this._getContent()}setContent(t){this._sanitizeAndSetContent(t,this.getTitle(),".popover-header"),this._sanitizeAndSetContent(t,this._getContent(),".popover-body")}_getContent(){return this._resolvePossibleFunction(this._config.content)}_getBasicClassPrefix(){return"bs-popover"}static jQueryInterface(t){return this.each((function(){const e=gn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}g(gn);const _n="scrollspy",bn={offset:10,method:"auto",target:""},vn={offset:"number",method:"string",target:"(string|element)"},yn="active",wn=".nav-link, .list-group-item, .dropdown-item",En="position";class An extends B{constructor(t,e){super(t),this._scrollElement="BODY"===this._element.tagName?window:this._element,this._config=this._getConfig(e),this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,j.on(this._scrollElement,"scroll.bs.scrollspy",(()=>this._process())),this.refresh(),this._process()}static get Default(){return bn}static get NAME(){return _n}refresh(){const t=this._scrollElement===this._scrollElement.window?"offset":En,e="auto"===this._config.method?t:this._config.method,n=e===En?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),V.find(wn,this._config.target).map((t=>{const s=i(t),o=s?V.findOne(s):null;if(o){const t=o.getBoundingClientRect();if(t.width||t.height)return[U[e](o).top+n,s]}return null})).filter((t=>t)).sort(((t,e)=>t[0]-e[0])).forEach((t=>{this._offsets.push(t[0]),this._targets.push(t[1])}))}dispose(){j.off(this._scrollElement,".bs.scrollspy"),super.dispose()}_getConfig(t){return(t={...bn,...U.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}}).target=r(t.target)||document.documentElement,a(_n,t,vn),t}_getScrollTop(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop}_getScrollHeight(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)}_getOffsetHeight(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height}_process(){const t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),i=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=i){const t=this._targets[this._targets.length-1];this._activeTarget!==t&&this._activate(t)}else{if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(let e=this._offsets.length;e--;)this._activeTarget!==this._targets[e]&&t>=this._offsets[e]&&(void 0===this._offsets[e+1]||t`${e}[data-bs-target="${t}"],${e}[href="${t}"]`)),i=V.findOne(e.join(","),this._config.target);i.classList.add(yn),i.classList.contains("dropdown-item")?V.findOne(".dropdown-toggle",i.closest(".dropdown")).classList.add(yn):V.parents(i,".nav, .list-group").forEach((t=>{V.prev(t,".nav-link, .list-group-item").forEach((t=>t.classList.add(yn))),V.prev(t,".nav-item").forEach((t=>{V.children(t,".nav-link").forEach((t=>t.classList.add(yn)))}))})),j.trigger(this._scrollElement,"activate.bs.scrollspy",{relatedTarget:t})}_clear(){V.find(wn,this._config.target).filter((t=>t.classList.contains(yn))).forEach((t=>t.classList.remove(yn)))}static jQueryInterface(t){return this.each((function(){const e=An.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}j.on(window,"load.bs.scrollspy.data-api",(()=>{V.find('[data-bs-spy="scroll"]').forEach((t=>new An(t)))})),g(An);const Tn="active",On="fade",Cn="show",kn=".active",Ln=":scope > li > .active";class xn extends B{static get NAME(){return"tab"}show(){if(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&this._element.classList.contains(Tn))return;let t;const e=n(this._element),i=this._element.closest(".nav, .list-group");if(i){const e="UL"===i.nodeName||"OL"===i.nodeName?Ln:kn;t=V.find(e,i),t=t[t.length-1]}const s=t?j.trigger(t,"hide.bs.tab",{relatedTarget:this._element}):null;if(j.trigger(this._element,"show.bs.tab",{relatedTarget:t}).defaultPrevented||null!==s&&s.defaultPrevented)return;this._activate(this._element,i);const o=()=>{j.trigger(t,"hidden.bs.tab",{relatedTarget:this._element}),j.trigger(this._element,"shown.bs.tab",{relatedTarget:t})};e?this._activate(e,e.parentNode,o):o()}_activate(t,e,i){const n=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?V.children(e,kn):V.find(Ln,e))[0],s=i&&n&&n.classList.contains(On),o=()=>this._transitionComplete(t,n,i);n&&s?(n.classList.remove(Cn),this._queueCallback(o,t,!0)):o()}_transitionComplete(t,e,i){if(e){e.classList.remove(Tn);const t=V.findOne(":scope > .dropdown-menu .active",e.parentNode);t&&t.classList.remove(Tn),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}t.classList.add(Tn),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),u(t),t.classList.contains(On)&&t.classList.add(Cn);let n=t.parentNode;if(n&&"LI"===n.nodeName&&(n=n.parentNode),n&&n.classList.contains("dropdown-menu")){const e=t.closest(".dropdown");e&&V.find(".dropdown-toggle",e).forEach((t=>t.classList.add(Tn))),t.setAttribute("aria-expanded",!0)}i&&i()}static jQueryInterface(t){return this.each((function(){const e=xn.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}j.on(document,"click.bs.tab.data-api",'[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),c(this)||xn.getOrCreateInstance(this).show()})),g(xn);const Dn="toast",Sn="hide",Nn="show",In="showing",Pn={animation:"boolean",autohide:"boolean",delay:"number"},jn={animation:!0,autohide:!0,delay:5e3};class Mn extends B{constructor(t,e){super(t),this._config=this._getConfig(e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get DefaultType(){return Pn}static get Default(){return jn}static get NAME(){return Dn}show(){j.trigger(this._element,"show.bs.toast").defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(Sn),u(this._element),this._element.classList.add(Nn),this._element.classList.add(In),this._queueCallback((()=>{this._element.classList.remove(In),j.trigger(this._element,"shown.bs.toast"),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this._element.classList.contains(Nn)&&(j.trigger(this._element,"hide.bs.toast").defaultPrevented||(this._element.classList.add(In),this._queueCallback((()=>{this._element.classList.add(Sn),this._element.classList.remove(In),this._element.classList.remove(Nn),j.trigger(this._element,"hidden.bs.toast")}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this._element.classList.contains(Nn)&&this._element.classList.remove(Nn),super.dispose()}_getConfig(t){return t={...jn,...U.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}},a(Dn,t,this.constructor.DefaultType),t}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){j.on(this._element,"mouseover.bs.toast",(t=>this._onInteraction(t,!0))),j.on(this._element,"mouseout.bs.toast",(t=>this._onInteraction(t,!1))),j.on(this._element,"focusin.bs.toast",(t=>this._onInteraction(t,!0))),j.on(this._element,"focusout.bs.toast",(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=Mn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(Mn),g(Mn),{Alert:W,Button:z,Carousel:st,Collapse:pt,Dropdown:hi,Modal:Hi,Offcanvas:Fi,Popover:gn,ScrollSpy:An,Tab:xn,Toast:Mn,Tooltip:un}})); +//# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/public/site_libs/clipboard/clipboard.min.js b/public/site_libs/clipboard/clipboard.min.js new file mode 100644 index 00000000..1103f811 --- /dev/null +++ b/public/site_libs/clipboard/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return b}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),r=n.n(e);function c(t){try{return document.execCommand(t)}catch(t){return}}var a=function(t){t=r()(t);return c("cut"),t};function o(t,e){var n,o,t=(n=t,o="rtl"===document.documentElement.getAttribute("dir"),(t=document.createElement("textarea")).style.fontSize="12pt",t.style.border="0",t.style.padding="0",t.style.margin="0",t.style.position="absolute",t.style[o?"right":"left"]="-9999px",o=window.pageYOffset||document.documentElement.scrollTop,t.style.top="".concat(o,"px"),t.setAttribute("readonly",""),t.value=n,t);return e.container.appendChild(t),e=r()(t),c("copy"),t.remove(),e}var f=function(t){var e=1.container-fluid.crosstalk-bscols{margin-left:auto;margin-right:auto}.crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column{display:inline-block;padding-right:12px;vertical-align:top}@media only screen and (max-width: 480px){.crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column{display:block;padding-right:inherit}}.crosstalk-input{margin-bottom:15px}.crosstalk-input .control-label{margin-bottom:0;vertical-align:middle}.crosstalk-input input[type="checkbox"]{margin:4px 0 0;margin-top:1px;line-height:normal}.crosstalk-input .checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.crosstalk-input .checkbox>label{padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.crosstalk-input .checkbox input[type="checkbox"],.crosstalk-input .checkbox-inline input[type="checkbox"]{position:absolute;margin-top:2px;margin-left:-20px}.crosstalk-input .checkbox+.checkbox{margin-top:-5px}.crosstalk-input .checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.crosstalk-input .checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px} diff --git a/public/site_libs/crosstalk-1.2.0/js/crosstalk.js b/public/site_libs/crosstalk-1.2.0/js/crosstalk.js new file mode 100644 index 00000000..fd9eb53d --- /dev/null +++ b/public/site_libs/crosstalk-1.2.0/js/crosstalk.js @@ -0,0 +1,1474 @@ +(function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o b) { + return 1; + } +} + +/** + * @private + */ + +var FilterSet = function () { + function FilterSet() { + _classCallCheck(this, FilterSet); + + this.reset(); + } + + _createClass(FilterSet, [{ + key: "reset", + value: function reset() { + // Key: handle ID, Value: array of selected keys, or null + this._handles = {}; + // Key: key string, Value: count of handles that include it + this._keys = {}; + this._value = null; + this._activeHandles = 0; + } + }, { + key: "update", + value: function update(handleId, keys) { + if (keys !== null) { + keys = keys.slice(0); // clone before sorting + keys.sort(naturalComparator); + } + + var _diffSortedLists = (0, _util.diffSortedLists)(this._handles[handleId], keys), + added = _diffSortedLists.added, + removed = _diffSortedLists.removed; + + this._handles[handleId] = keys; + + for (var i = 0; i < added.length; i++) { + this._keys[added[i]] = (this._keys[added[i]] || 0) + 1; + } + for (var _i = 0; _i < removed.length; _i++) { + this._keys[removed[_i]]--; + } + + this._updateValue(keys); + } + + /** + * @param {string[]} keys Sorted array of strings that indicate + * a superset of possible keys. + * @private + */ + + }, { + key: "_updateValue", + value: function _updateValue() { + var keys = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this._allKeys; + + var handleCount = Object.keys(this._handles).length; + if (handleCount === 0) { + this._value = null; + } else { + this._value = []; + for (var i = 0; i < keys.length; i++) { + var count = this._keys[keys[i]]; + if (count === handleCount) { + this._value.push(keys[i]); + } + } + } + } + }, { + key: "clear", + value: function clear(handleId) { + if (typeof this._handles[handleId] === "undefined") { + return; + } + + var keys = this._handles[handleId]; + if (!keys) { + keys = []; + } + + for (var i = 0; i < keys.length; i++) { + this._keys[keys[i]]--; + } + delete this._handles[handleId]; + + this._updateValue(); + } + }, { + key: "value", + get: function get() { + return this._value; + } + }, { + key: "_allKeys", + get: function get() { + var allKeys = Object.keys(this._keys); + allKeys.sort(naturalComparator); + return allKeys; + } + }]); + + return FilterSet; +}(); + +exports.default = FilterSet; + +},{"./util":11}],4:[function(require,module,exports){ +(function (global){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +exports.default = group; + +var _var2 = require("./var"); + +var _var3 = _interopRequireDefault(_var2); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +// Use a global so that multiple copies of crosstalk.js can be loaded and still +// have groups behave as singletons across all copies. +global.__crosstalk_groups = global.__crosstalk_groups || {}; +var groups = global.__crosstalk_groups; + +function group(groupName) { + if (groupName && typeof groupName === "string") { + if (!groups.hasOwnProperty(groupName)) { + groups[groupName] = new Group(groupName); + } + return groups[groupName]; + } else if ((typeof groupName === "undefined" ? "undefined" : _typeof(groupName)) === "object" && groupName._vars && groupName.var) { + // Appears to already be a group object + return groupName; + } else if (Array.isArray(groupName) && groupName.length == 1 && typeof groupName[0] === "string") { + return group(groupName[0]); + } else { + throw new Error("Invalid groupName argument"); + } +} + +var Group = function () { + function Group(name) { + _classCallCheck(this, Group); + + this.name = name; + this._vars = {}; + } + + _createClass(Group, [{ + key: "var", + value: function _var(name) { + if (!name || typeof name !== "string") { + throw new Error("Invalid var name"); + } + + if (!this._vars.hasOwnProperty(name)) this._vars[name] = new _var3.default(this, name); + return this._vars[name]; + } + }, { + key: "has", + value: function has(name) { + if (!name || typeof name !== "string") { + throw new Error("Invalid var name"); + } + + return this._vars.hasOwnProperty(name); + } + }]); + + return Group; +}(); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./var":12}],5:[function(require,module,exports){ +(function (global){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _group = require("./group"); + +var _group2 = _interopRequireDefault(_group); + +var _selection = require("./selection"); + +var _filter = require("./filter"); + +var _input = require("./input"); + +require("./input_selectize"); + +require("./input_checkboxgroup"); + +require("./input_slider"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var defaultGroup = (0, _group2.default)("default"); + +function var_(name) { + return defaultGroup.var(name); +} + +function has(name) { + return defaultGroup.has(name); +} + +if (global.Shiny) { + global.Shiny.addCustomMessageHandler("update-client-value", function (message) { + if (typeof message.group === "string") { + (0, _group2.default)(message.group).var(message.name).set(message.value); + } else { + var_(message.name).set(message.value); + } + }); +} + +var crosstalk = { + group: _group2.default, + var: var_, + has: has, + SelectionHandle: _selection.SelectionHandle, + FilterHandle: _filter.FilterHandle, + bind: _input.bind +}; + +/** + * @namespace crosstalk + */ +exports.default = crosstalk; + +global.crosstalk = crosstalk; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./filter":2,"./group":4,"./input":6,"./input_checkboxgroup":7,"./input_selectize":8,"./input_slider":9,"./selection":10}],6:[function(require,module,exports){ +(function (global){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.register = register; +exports.bind = bind; +var $ = global.jQuery; + +var bindings = {}; + +function register(reg) { + bindings[reg.className] = reg; + if (global.document && global.document.readyState !== "complete") { + $(function () { + bind(); + }); + } else if (global.document) { + setTimeout(bind, 100); + } +} + +function bind() { + Object.keys(bindings).forEach(function (className) { + var binding = bindings[className]; + $("." + binding.className).not(".crosstalk-input-bound").each(function (i, el) { + bindInstance(binding, el); + }); + }); +} + +// Escape jQuery identifier +function $escape(val) { + return val.replace(/([!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~])/g, "\\$1"); +} + +function bindEl(el) { + var $el = $(el); + Object.keys(bindings).forEach(function (className) { + if ($el.hasClass(className) && !$el.hasClass("crosstalk-input-bound")) { + var binding = bindings[className]; + bindInstance(binding, el); + } + }); +} + +function bindInstance(binding, el) { + var jsonEl = $(el).find("script[type='application/json'][data-for='" + $escape(el.id) + "']"); + var data = JSON.parse(jsonEl[0].innerText); + + var instance = binding.factory(el, data); + $(el).data("crosstalk-instance", instance); + $(el).addClass("crosstalk-input-bound"); +} + +if (global.Shiny) { + var inputBinding = new global.Shiny.InputBinding(); + var _$ = global.jQuery; + _$.extend(inputBinding, { + find: function find(scope) { + return _$(scope).find(".crosstalk-input"); + }, + initialize: function initialize(el) { + if (!_$(el).hasClass("crosstalk-input-bound")) { + bindEl(el); + } + }, + getId: function getId(el) { + return el.id; + }, + getValue: function getValue(el) {}, + setValue: function setValue(el, value) {}, + receiveMessage: function receiveMessage(el, data) {}, + subscribe: function subscribe(el, callback) { + _$(el).data("crosstalk-instance").resume(); + }, + unsubscribe: function unsubscribe(el) { + _$(el).data("crosstalk-instance").suspend(); + } + }); + global.Shiny.inputBindings.register(inputBinding, "crosstalk.inputBinding"); +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],7:[function(require,module,exports){ +(function (global){ +"use strict"; + +var _input = require("./input"); + +var input = _interopRequireWildcard(_input); + +var _filter = require("./filter"); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +var $ = global.jQuery; + +input.register({ + className: "crosstalk-input-checkboxgroup", + + factory: function factory(el, data) { + /* + * map: {"groupA": ["keyA", "keyB", ...], ...} + * group: "ct-groupname" + */ + var ctHandle = new _filter.FilterHandle(data.group); + + var lastKnownKeys = void 0; + var $el = $(el); + $el.on("change", "input[type='checkbox']", function () { + var checked = $el.find("input[type='checkbox']:checked"); + if (checked.length === 0) { + lastKnownKeys = null; + ctHandle.clear(); + } else { + var keys = {}; + checked.each(function () { + data.map[this.value].forEach(function (key) { + keys[key] = true; + }); + }); + var keyArray = Object.keys(keys); + keyArray.sort(); + lastKnownKeys = keyArray; + ctHandle.set(keyArray); + } + }); + + return { + suspend: function suspend() { + ctHandle.clear(); + }, + resume: function resume() { + if (lastKnownKeys) ctHandle.set(lastKnownKeys); + } + }; + } +}); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./filter":2,"./input":6}],8:[function(require,module,exports){ +(function (global){ +"use strict"; + +var _input = require("./input"); + +var input = _interopRequireWildcard(_input); + +var _util = require("./util"); + +var util = _interopRequireWildcard(_util); + +var _filter = require("./filter"); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +var $ = global.jQuery; + +input.register({ + className: "crosstalk-input-select", + + factory: function factory(el, data) { + /* + * items: {value: [...], label: [...]} + * map: {"groupA": ["keyA", "keyB", ...], ...} + * group: "ct-groupname" + */ + + var first = [{ value: "", label: "(All)" }]; + var items = util.dataframeToD3(data.items); + var opts = { + options: first.concat(items), + valueField: "value", + labelField: "label", + searchField: "label" + }; + + var select = $(el).find("select")[0]; + + var selectize = $(select).selectize(opts)[0].selectize; + + var ctHandle = new _filter.FilterHandle(data.group); + + var lastKnownKeys = void 0; + selectize.on("change", function () { + if (selectize.items.length === 0) { + lastKnownKeys = null; + ctHandle.clear(); + } else { + var keys = {}; + selectize.items.forEach(function (group) { + data.map[group].forEach(function (key) { + keys[key] = true; + }); + }); + var keyArray = Object.keys(keys); + keyArray.sort(); + lastKnownKeys = keyArray; + ctHandle.set(keyArray); + } + }); + + return { + suspend: function suspend() { + ctHandle.clear(); + }, + resume: function resume() { + if (lastKnownKeys) ctHandle.set(lastKnownKeys); + } + }; + } +}); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./filter":2,"./input":6,"./util":11}],9:[function(require,module,exports){ +(function (global){ +"use strict"; + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +var _input = require("./input"); + +var input = _interopRequireWildcard(_input); + +var _filter = require("./filter"); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +var $ = global.jQuery; +var strftime = global.strftime; + +input.register({ + className: "crosstalk-input-slider", + + factory: function factory(el, data) { + /* + * map: {"groupA": ["keyA", "keyB", ...], ...} + * group: "ct-groupname" + */ + var ctHandle = new _filter.FilterHandle(data.group); + + var opts = {}; + var $el = $(el).find("input"); + var dataType = $el.data("data-type"); + var timeFormat = $el.data("time-format"); + var round = $el.data("round"); + var timeFormatter = void 0; + + // Set up formatting functions + if (dataType === "date") { + timeFormatter = strftime.utc(); + opts.prettify = function (num) { + return timeFormatter(timeFormat, new Date(num)); + }; + } else if (dataType === "datetime") { + var timezone = $el.data("timezone"); + if (timezone) timeFormatter = strftime.timezone(timezone);else timeFormatter = strftime; + + opts.prettify = function (num) { + return timeFormatter(timeFormat, new Date(num)); + }; + } else if (dataType === "number") { + if (typeof round !== "undefined") opts.prettify = function (num) { + var factor = Math.pow(10, round); + return Math.round(num * factor) / factor; + }; + } + + $el.ionRangeSlider(opts); + + function getValue() { + var result = $el.data("ionRangeSlider").result; + + // Function for converting numeric value from slider to appropriate type. + var convert = void 0; + var dataType = $el.data("data-type"); + if (dataType === "date") { + convert = function convert(val) { + return formatDateUTC(new Date(+val)); + }; + } else if (dataType === "datetime") { + convert = function convert(val) { + // Convert ms to s + return +val / 1000; + }; + } else { + convert = function convert(val) { + return +val; + }; + } + + if ($el.data("ionRangeSlider").options.type === "double") { + return [convert(result.from), convert(result.to)]; + } else { + return convert(result.from); + } + } + + var lastKnownKeys = null; + + $el.on("change.crosstalkSliderInput", function (event) { + if (!$el.data("updating") && !$el.data("animating")) { + var _getValue = getValue(), + _getValue2 = _slicedToArray(_getValue, 2), + from = _getValue2[0], + to = _getValue2[1]; + + var keys = []; + for (var i = 0; i < data.values.length; i++) { + var val = data.values[i]; + if (val >= from && val <= to) { + keys.push(data.keys[i]); + } + } + keys.sort(); + ctHandle.set(keys); + lastKnownKeys = keys; + } + }); + + // let $el = $(el); + // $el.on("change", "input[type="checkbox"]", function() { + // let checked = $el.find("input[type="checkbox"]:checked"); + // if (checked.length === 0) { + // ctHandle.clear(); + // } else { + // let keys = {}; + // checked.each(function() { + // data.map[this.value].forEach(function(key) { + // keys[key] = true; + // }); + // }); + // let keyArray = Object.keys(keys); + // keyArray.sort(); + // ctHandle.set(keyArray); + // } + // }); + + return { + suspend: function suspend() { + ctHandle.clear(); + }, + resume: function resume() { + if (lastKnownKeys) ctHandle.set(lastKnownKeys); + } + }; + } +}); + +// Convert a number to a string with leading zeros +function padZeros(n, digits) { + var str = n.toString(); + while (str.length < digits) { + str = "0" + str; + }return str; +} + +// Given a Date object, return a string in yyyy-mm-dd format, using the +// UTC date. This may be a day off from the date in the local time zone. +function formatDateUTC(date) { + if (date instanceof Date) { + return date.getUTCFullYear() + "-" + padZeros(date.getUTCMonth() + 1, 2) + "-" + padZeros(date.getUTCDate(), 2); + } else { + return null; + } +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./filter":2,"./input":6}],10:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.SelectionHandle = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _events = require("./events"); + +var _events2 = _interopRequireDefault(_events); + +var _group = require("./group"); + +var _group2 = _interopRequireDefault(_group); + +var _util = require("./util"); + +var util = _interopRequireWildcard(_util); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Use this class to read and write (and listen for changes to) the selection + * for a Crosstalk group. This is intended to be used for linked brushing. + * + * If two (or more) `SelectionHandle` instances in the same webpage share the + * same group name, they will share the same state. Setting the selection using + * one `SelectionHandle` instance will result in the `value` property instantly + * changing across the others, and `"change"` event listeners on all instances + * (including the one that initiated the sending) will fire. + * + * @param {string} [group] - The name of the Crosstalk group, or if none, + * null or undefined (or any other falsy value). This can be changed later + * via the [SelectionHandle#setGroup](#setGroup) method. + * @param {Object} [extraInfo] - An object whose properties will be copied to + * the event object whenever an event is emitted. + */ +var SelectionHandle = exports.SelectionHandle = function () { + function SelectionHandle() { + var group = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + var extraInfo = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + + _classCallCheck(this, SelectionHandle); + + this._eventRelay = new _events2.default(); + this._emitter = new util.SubscriptionTracker(this._eventRelay); + + // Name of the group we're currently tracking, if any. Can change over time. + this._group = null; + // The Var we're currently tracking, if any. Can change over time. + this._var = null; + // The event handler subscription we currently have on var.on("change"). + this._varOnChangeSub = null; + + this._extraInfo = util.extend({ sender: this }, extraInfo); + + this.setGroup(group); + } + + /** + * Changes the Crosstalk group membership of this SelectionHandle. The group + * being switched away from (if any) will not have its selection value + * modified as a result of calling `setGroup`, even if this handle was the + * most recent handle to set the selection of the group. + * + * The group being switched to (if any) will also not have its selection value + * modified as a result of calling `setGroup`. If you want to set the + * selection value of the new group, call `set` explicitly. + * + * @param {string} group - The name of the Crosstalk group, or null (or + * undefined) to clear the group. + */ + + + _createClass(SelectionHandle, [{ + key: "setGroup", + value: function setGroup(group) { + var _this = this; + + // If group is unchanged, do nothing + if (this._group === group) return; + // Treat null, undefined, and other falsy values the same + if (!this._group && !group) return; + + if (this._var) { + this._var.off("change", this._varOnChangeSub); + this._var = null; + this._varOnChangeSub = null; + } + + this._group = group; + + if (group) { + this._var = (0, _group2.default)(group).var("selection"); + var sub = this._var.on("change", function (e) { + _this._eventRelay.trigger("change", e, _this); + }); + this._varOnChangeSub = sub; + } + } + + /** + * Retrieves the current selection for the group represented by this + * `SelectionHandle`. + * + * - If no selection is active, then this value will be falsy. + * - If a selection is active, but no data points are selected, then this + * value will be an empty array. + * - If a selection is active, and data points are selected, then the keys + * of the selected data points will be present in the array. + */ + + }, { + key: "_mergeExtraInfo", + + + /** + * Combines the given `extraInfo` (if any) with the handle's default + * `_extraInfo` (if any). + * @private + */ + value: function _mergeExtraInfo(extraInfo) { + // Important incidental effect: shallow clone is returned + return util.extend({}, this._extraInfo ? this._extraInfo : null, extraInfo ? extraInfo : null); + } + + /** + * Overwrites the current selection for the group, and raises the `"change"` + * event among all of the group's '`SelectionHandle` instances (including + * this one). + * + * @fires SelectionHandle#change + * @param {string[]} selectedKeys - Falsy, empty array, or array of keys (see + * {@link SelectionHandle#value}). + * @param {Object} [extraInfo] - Extra properties to be included on the event + * object that's passed to listeners (in addition to any options that were + * passed into the `SelectionHandle` constructor). + */ + + }, { + key: "set", + value: function set(selectedKeys, extraInfo) { + if (this._var) this._var.set(selectedKeys, this._mergeExtraInfo(extraInfo)); + } + + /** + * Overwrites the current selection for the group, and raises the `"change"` + * event among all of the group's '`SelectionHandle` instances (including + * this one). + * + * @fires SelectionHandle#change + * @param {Object} [extraInfo] - Extra properties to be included on the event + * object that's passed to listeners (in addition to any that were passed + * into the `SelectionHandle` constructor). + */ + + }, { + key: "clear", + value: function clear(extraInfo) { + if (this._var) this.set(void 0, this._mergeExtraInfo(extraInfo)); + } + + /** + * Subscribes to events on this `SelectionHandle`. + * + * @param {string} eventType - Indicates the type of events to listen to. + * Currently, only `"change"` is supported. + * @param {SelectionHandle~listener} listener - The callback function that + * will be invoked when the event occurs. + * @return {string} - A token to pass to {@link SelectionHandle#off} to cancel + * this subscription. + */ + + }, { + key: "on", + value: function on(eventType, listener) { + return this._emitter.on(eventType, listener); + } + + /** + * Cancels event subscriptions created by {@link SelectionHandle#on}. + * + * @param {string} eventType - The type of event to unsubscribe. + * @param {string|SelectionHandle~listener} listener - Either the callback + * function previously passed into {@link SelectionHandle#on}, or the + * string that was returned from {@link SelectionHandle#on}. + */ + + }, { + key: "off", + value: function off(eventType, listener) { + return this._emitter.off(eventType, listener); + } + + /** + * Shuts down the `SelectionHandle` object. + * + * Removes all event listeners that were added through this handle. + */ + + }, { + key: "close", + value: function close() { + this._emitter.removeAllListeners(); + this.setGroup(null); + } + }, { + key: "value", + get: function get() { + return this._var ? this._var.get() : null; + } + }]); + + return SelectionHandle; +}(); + +/** + * @callback SelectionHandle~listener + * @param {Object} event - An object containing details of the event. For + * `"change"` events, this includes the properties `value` (the new + * value of the selection, or `undefined` if no selection is active), + * `oldValue` (the previous value of the selection), and `sender` (the + * `SelectionHandle` instance that made the change). + */ + +/** + * @event SelectionHandle#change + * @type {object} + * @property {object} value - The new value of the selection, or `undefined` + * if no selection is active. + * @property {object} oldValue - The previous value of the selection. + * @property {SelectionHandle} sender - The `SelectionHandle` instance that + * changed the value. + */ + +},{"./events":1,"./group":4,"./util":11}],11:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +exports.extend = extend; +exports.checkSorted = checkSorted; +exports.diffSortedLists = diffSortedLists; +exports.dataframeToD3 = dataframeToD3; + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function extend(target) { + for (var _len = arguments.length, sources = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + sources[_key - 1] = arguments[_key]; + } + + for (var i = 0; i < sources.length; i++) { + var src = sources[i]; + if (typeof src === "undefined" || src === null) continue; + + for (var key in src) { + if (src.hasOwnProperty(key)) { + target[key] = src[key]; + } + } + } + return target; +} + +function checkSorted(list) { + for (var i = 1; i < list.length; i++) { + if (list[i] <= list[i - 1]) { + throw new Error("List is not sorted or contains duplicate"); + } + } +} + +function diffSortedLists(a, b) { + var i_a = 0; + var i_b = 0; + + if (!a) a = []; + if (!b) b = []; + + var a_only = []; + var b_only = []; + + checkSorted(a); + checkSorted(b); + + while (i_a < a.length && i_b < b.length) { + if (a[i_a] === b[i_b]) { + i_a++; + i_b++; + } else if (a[i_a] < b[i_b]) { + a_only.push(a[i_a++]); + } else { + b_only.push(b[i_b++]); + } + } + + if (i_a < a.length) a_only = a_only.concat(a.slice(i_a)); + if (i_b < b.length) b_only = b_only.concat(b.slice(i_b)); + return { + removed: a_only, + added: b_only + }; +} + +// Convert from wide: { colA: [1,2,3], colB: [4,5,6], ... } +// to long: [ {colA: 1, colB: 4}, {colA: 2, colB: 5}, ... ] +function dataframeToD3(df) { + var names = []; + var length = void 0; + for (var name in df) { + if (df.hasOwnProperty(name)) names.push(name); + if (_typeof(df[name]) !== "object" || typeof df[name].length === "undefined") { + throw new Error("All fields must be arrays"); + } else if (typeof length !== "undefined" && length !== df[name].length) { + throw new Error("All fields must be arrays of the same length"); + } + length = df[name].length; + } + var results = []; + var item = void 0; + for (var row = 0; row < length; row++) { + item = {}; + for (var col = 0; col < names.length; col++) { + item[names[col]] = df[names[col]][row]; + } + results.push(item); + } + return results; +} + +/** + * Keeps track of all event listener additions/removals and lets all active + * listeners be removed with a single operation. + * + * @private + */ + +var SubscriptionTracker = exports.SubscriptionTracker = function () { + function SubscriptionTracker(emitter) { + _classCallCheck(this, SubscriptionTracker); + + this._emitter = emitter; + this._subs = {}; + } + + _createClass(SubscriptionTracker, [{ + key: "on", + value: function on(eventType, listener) { + var sub = this._emitter.on(eventType, listener); + this._subs[sub] = eventType; + return sub; + } + }, { + key: "off", + value: function off(eventType, listener) { + var sub = this._emitter.off(eventType, listener); + if (sub) { + delete this._subs[sub]; + } + return sub; + } + }, { + key: "removeAllListeners", + value: function removeAllListeners() { + var _this = this; + + var current_subs = this._subs; + this._subs = {}; + Object.keys(current_subs).forEach(function (sub) { + _this._emitter.off(current_subs[sub], sub); + }); + } + }]); + + return SubscriptionTracker; +}(); + +},{}],12:[function(require,module,exports){ +(function (global){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _events = require("./events"); + +var _events2 = _interopRequireDefault(_events); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Var = function () { + function Var(group, name, /*optional*/value) { + _classCallCheck(this, Var); + + this._group = group; + this._name = name; + this._value = value; + this._events = new _events2.default(); + } + + _createClass(Var, [{ + key: "get", + value: function get() { + return this._value; + } + }, { + key: "set", + value: function set(value, /*optional*/event) { + if (this._value === value) { + // Do nothing; the value hasn't changed + return; + } + var oldValue = this._value; + this._value = value; + // Alert JavaScript listeners that the value has changed + var evt = {}; + if (event && (typeof event === "undefined" ? "undefined" : _typeof(event)) === "object") { + for (var k in event) { + if (event.hasOwnProperty(k)) evt[k] = event[k]; + } + } + evt.oldValue = oldValue; + evt.value = value; + this._events.trigger("change", evt, this); + + // TODO: Make this extensible, to let arbitrary back-ends know that + // something has changed + if (global.Shiny && global.Shiny.onInputChange) { + global.Shiny.onInputChange(".clientValue-" + (this._group.name !== null ? this._group.name + "-" : "") + this._name, typeof value === "undefined" ? null : value); + } + } + }, { + key: "on", + value: function on(eventType, listener) { + return this._events.on(eventType, listener); + } + }, { + key: "off", + value: function off(eventType, listener) { + return this._events.off(eventType, listener); + } + }]); + + return Var; +}(); + +exports.default = Var; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./events":1}]},{},[5]) +//# sourceMappingURL=crosstalk.js.map diff --git a/public/site_libs/crosstalk-1.2.0/js/crosstalk.js.map b/public/site_libs/crosstalk-1.2.0/js/crosstalk.js.map new file mode 100644 index 00000000..cff94f08 --- /dev/null +++ b/public/site_libs/crosstalk-1.2.0/js/crosstalk.js.map @@ -0,0 +1,37 @@ +{ + "version": 3, + "sources": [ + "node_modules/browser-pack/_prelude.js", + "javascript/src/events.js", + "javascript/src/filter.js", + "javascript/src/filterset.js", + "javascript/src/group.js", + "javascript/src/index.js", + "javascript/src/input.js", + "javascript/src/input_checkboxgroup.js", + "javascript/src/input_selectize.js", + "javascript/src/input_slider.js", + "javascript/src/selection.js", + "javascript/src/util.js", + "javascript/src/var.js" + ], + "names": [], + "mappings": "AAAA;;;;;;;;;;;ICAqB,M;AACnB,oBAAc;AAAA;;AACZ,SAAK,MAAL,GAAc,EAAd;AACA,SAAK,IAAL,GAAY,CAAZ;AACD;;;;uBAEE,S,EAAW,Q,EAAU;AACtB,UAAI,OAAO,KAAK,MAAL,CAAY,SAAZ,CAAX;AACA,UAAI,CAAC,IAAL,EAAW;AACT,eAAO,KAAK,MAAL,CAAY,SAAZ,IAAyB,EAAhC;AACD;AACD,UAAI,MAAM,QAAS,KAAK,IAAL,EAAnB;AACA,WAAK,GAAL,IAAY,QAAZ;AACA,aAAO,GAAP;AACD;;AAED;;;;wBACI,S,EAAW,Q,EAAU;AACvB,UAAI,OAAO,KAAK,MAAL,CAAY,SAAZ,CAAX;AACA,UAAI,OAAO,QAAP,KAAqB,UAAzB,EAAqC;AACnC,aAAK,IAAI,GAAT,IAAgB,IAAhB,EAAsB;AACpB,cAAI,KAAK,cAAL,CAAoB,GAApB,CAAJ,EAA8B;AAC5B,gBAAI,KAAK,GAAL,MAAc,QAAlB,EAA4B;AAC1B,qBAAO,KAAK,GAAL,CAAP;AACA,qBAAO,GAAP;AACD;AACF;AACF;AACD,eAAO,KAAP;AACD,OAVD,MAUO,IAAI,OAAO,QAAP,KAAqB,QAAzB,EAAmC;AACxC,YAAI,QAAQ,KAAK,QAAL,CAAZ,EAA4B;AAC1B,iBAAO,KAAK,QAAL,CAAP;AACA,iBAAO,QAAP;AACD;AACD,eAAO,KAAP;AACD,OANM,MAMA;AACL,cAAM,IAAI,KAAJ,CAAU,8BAAV,CAAN;AACD;AACF;;;4BAEO,S,EAAW,G,EAAK,O,EAAS;AAC/B,UAAI,OAAO,KAAK,MAAL,CAAY,SAAZ,CAAX;AACA,WAAK,IAAI,GAAT,IAAgB,IAAhB,EAAsB;AACpB,YAAI,KAAK,cAAL,CAAoB,GAApB,CAAJ,EAA8B;AAC5B,eAAK,GAAL,EAAU,IAAV,CAAe,OAAf,EAAwB,GAAxB;AACD;AACF;AACF;;;;;;kBA/CkB,M;;;;;;;;;;;;ACArB;;;;AACA;;;;AACA;;;;AACA;;IAAY,I;;;;;;;;AAEZ,SAAS,YAAT,CAAsB,KAAtB,EAA6B;AAC3B,MAAI,QAAQ,MAAM,GAAN,CAAU,WAAV,CAAZ;AACA,MAAI,SAAS,MAAM,GAAN,EAAb;AACA,MAAI,CAAC,MAAL,EAAa;AACX,aAAS,yBAAT;AACA,UAAM,GAAN,CAAU,MAAV;AACD;AACD,SAAO,MAAP;AACD;;AAED,IAAI,KAAK,CAAT;AACA,SAAS,MAAT,GAAkB;AAChB,SAAO,IAAP;AACD;;AAED;;;;;;;;;;;;;;;;;;;;;;;;;IAwBa,Y,WAAA,Y;AACX,wBAAY,KAAZ,EAAmB,SAAnB,EAA8B;AAAA;;AAC5B,SAAK,WAAL,GAAmB,sBAAnB;AACA,SAAK,QAAL,GAAgB,IAAI,KAAK,mBAAT,CAA6B,KAAK,WAAlC,CAAhB;;AAEA;AACA,SAAK,MAAL,GAAc,IAAd;AACA;AACA,SAAK,UAAL,GAAkB,IAAlB;AACA;AACA,SAAK,UAAL,GAAkB,IAAlB;AACA;AACA,SAAK,eAAL,GAAuB,IAAvB;;AAEA,SAAK,UAAL,GAAkB,KAAK,MAAL,CAAY,EAAE,QAAQ,IAAV,EAAZ,EAA8B,SAA9B,CAAlB;;AAEA,SAAK,GAAL,GAAW,WAAW,QAAtB;;AAEA,SAAK,QAAL,CAAc,KAAd;AACD;;AAED;;;;;;;;;;;;;;6BAUS,K,EAAO;AAAA;;AACd;AACA,UAAI,KAAK,MAAL,KAAgB,KAApB,EACE;AACF;AACA,UAAI,CAAC,KAAK,MAAN,IAAgB,CAAC,KAArB,EACE;;AAEF,UAAI,KAAK,UAAT,EAAqB;AACnB,aAAK,UAAL,CAAgB,GAAhB,CAAoB,QAApB,EAA8B,KAAK,eAAnC;AACA,aAAK,KAAL;AACA,aAAK,eAAL,GAAuB,IAAvB;AACA,aAAK,UAAL,GAAkB,IAAlB;AACA,aAAK,UAAL,GAAkB,IAAlB;AACD;;AAED,WAAK,MAAL,GAAc,KAAd;;AAEA,UAAI,KAAJ,EAAW;AACT,gBAAQ,qBAAI,KAAJ,CAAR;AACA,aAAK,UAAL,GAAkB,aAAa,KAAb,CAAlB;AACA,aAAK,UAAL,GAAkB,qBAAI,KAAJ,EAAW,GAAX,CAAe,QAAf,CAAlB;AACA,YAAI,MAAM,KAAK,UAAL,CAAgB,EAAhB,CAAmB,QAAnB,EAA6B,UAAC,CAAD,EAAO;AAC5C,gBAAK,WAAL,CAAiB,OAAjB,CAAyB,QAAzB,EAAmC,CAAnC;AACD,SAFS,CAAV;AAGA,aAAK,eAAL,GAAuB,GAAvB;AACD;AACF;;AAED;;;;;;;;oCAKgB,S,EAAW;AACzB,aAAO,KAAK,MAAL,CAAY,EAAZ,EACL,KAAK,UAAL,GAAkB,KAAK,UAAvB,GAAoC,IAD/B,EAEL,YAAY,SAAZ,GAAwB,IAFnB,CAAP;AAGD;;AAED;;;;;;;4BAIQ;AACN,WAAK,QAAL,CAAc,kBAAd;AACA,WAAK,KAAL;AACA,WAAK,QAAL,CAAc,IAAd;AACD;;AAED;;;;;;;;;;;;0BASM,S,EAAW;AACf,UAAI,CAAC,KAAK,UAAV,EACE;AACF,WAAK,UAAL,CAAgB,KAAhB,CAAsB,KAAK,GAA3B;AACA,WAAK,SAAL,CAAe,SAAf;AACD;;AAED;;;;;;;;;;;;;;;;;;;;wBAiBI,I,EAAM,S,EAAW;AACnB,UAAI,CAAC,KAAK,UAAV,EACE;AACF,WAAK,UAAL,CAAgB,MAAhB,CAAuB,KAAK,GAA5B,EAAiC,IAAjC;AACA,WAAK,SAAL,CAAe,SAAf;AACD;;AAED;;;;;;;;;;AASA;;;;;;;;;;uBAUG,S,EAAW,Q,EAAU;AACtB,aAAO,KAAK,QAAL,CAAc,EAAd,CAAiB,SAAjB,EAA4B,QAA5B,CAAP;AACD;;AAED;;;;;;;;;;;wBAQI,S,EAAW,Q,EAAU;AACvB,aAAO,KAAK,QAAL,CAAc,GAAd,CAAkB,SAAlB,EAA6B,QAA7B,CAAP;AACD;;;8BAES,S,EAAW;AACnB,UAAI,CAAC,KAAK,UAAV,EACE;AACF,WAAK,UAAL,CAAgB,GAAhB,CAAoB,KAAK,UAAL,CAAgB,KAApC,EAA2C,KAAK,eAAL,CAAqB,SAArB,CAA3C;AACD;;AAED;;;;;;;;;;;wBApCmB;AACjB,aAAO,KAAK,UAAL,GAAkB,KAAK,UAAL,CAAgB,KAAlC,GAA0C,IAAjD;AACD;;;;;;AA6CH;;;;;;;;;;;;;;;;;;;ACzNA;;;;AAEA,SAAS,iBAAT,CAA2B,CAA3B,EAA8B,CAA9B,EAAiC;AAC/B,MAAI,MAAM,CAAV,EAAa;AACX,WAAO,CAAP;AACD,GAFD,MAEO,IAAI,IAAI,CAAR,EAAW;AAChB,WAAO,CAAC,CAAR;AACD,GAFM,MAEA,IAAI,IAAI,CAAR,EAAW;AAChB,WAAO,CAAP;AACD;AACF;;AAED;;;;IAGqB,S;AACnB,uBAAc;AAAA;;AACZ,SAAK,KAAL;AACD;;;;4BAEO;AACN;AACA,WAAK,QAAL,GAAgB,EAAhB;AACA;AACA,WAAK,KAAL,GAAa,EAAb;AACA,WAAK,MAAL,GAAc,IAAd;AACA,WAAK,cAAL,GAAsB,CAAtB;AACD;;;2BAMM,Q,EAAU,I,EAAM;AACrB,UAAI,SAAS,IAAb,EAAmB;AACjB,eAAO,KAAK,KAAL,CAAW,CAAX,CAAP,CADiB,CACK;AACtB,aAAK,IAAL,CAAU,iBAAV;AACD;;AAJoB,6BAME,2BAAgB,KAAK,QAAL,CAAc,QAAd,CAAhB,EAAyC,IAAzC,CANF;AAAA,UAMhB,KANgB,oBAMhB,KANgB;AAAA,UAMT,OANS,oBAMT,OANS;;AAOrB,WAAK,QAAL,CAAc,QAAd,IAA0B,IAA1B;;AAEA,WAAK,IAAI,IAAI,CAAb,EAAgB,IAAI,MAAM,MAA1B,EAAkC,GAAlC,EAAuC;AACrC,aAAK,KAAL,CAAW,MAAM,CAAN,CAAX,IAAuB,CAAC,KAAK,KAAL,CAAW,MAAM,CAAN,CAAX,KAAwB,CAAzB,IAA8B,CAArD;AACD;AACD,WAAK,IAAI,KAAI,CAAb,EAAgB,KAAI,QAAQ,MAA5B,EAAoC,IAApC,EAAyC;AACvC,aAAK,KAAL,CAAW,QAAQ,EAAR,CAAX;AACD;;AAED,WAAK,YAAL,CAAkB,IAAlB;AACD;;AAED;;;;;;;;mCAKmC;AAAA,UAAtB,IAAsB,uEAAf,KAAK,QAAU;;AACjC,UAAI,cAAc,OAAO,IAAP,CAAY,KAAK,QAAjB,EAA2B,MAA7C;AACA,UAAI,gBAAgB,CAApB,EAAuB;AACrB,aAAK,MAAL,GAAc,IAAd;AACD,OAFD,MAEO;AACL,aAAK,MAAL,GAAc,EAAd;AACA,aAAK,IAAI,IAAI,CAAb,EAAgB,IAAI,KAAK,MAAzB,EAAiC,GAAjC,EAAsC;AACpC,cAAI,QAAQ,KAAK,KAAL,CAAW,KAAK,CAAL,CAAX,CAAZ;AACA,cAAI,UAAU,WAAd,EAA2B;AACzB,iBAAK,MAAL,CAAY,IAAZ,CAAiB,KAAK,CAAL,CAAjB;AACD;AACF;AACF;AACF;;;0BAEK,Q,EAAU;AACd,UAAI,OAAO,KAAK,QAAL,CAAc,QAAd,CAAP,KAAoC,WAAxC,EAAqD;AACnD;AACD;;AAED,UAAI,OAAO,KAAK,QAAL,CAAc,QAAd,CAAX;AACA,UAAI,CAAC,IAAL,EAAW;AACT,eAAO,EAAP;AACD;;AAED,WAAK,IAAI,IAAI,CAAb,EAAgB,IAAI,KAAK,MAAzB,EAAiC,GAAjC,EAAsC;AACpC,aAAK,KAAL,CAAW,KAAK,CAAL,CAAX;AACD;AACD,aAAO,KAAK,QAAL,CAAc,QAAd,CAAP;;AAEA,WAAK,YAAL;AACD;;;wBA3DW;AACV,aAAO,KAAK,MAAZ;AACD;;;wBA2Dc;AACb,UAAI,UAAU,OAAO,IAAP,CAAY,KAAK,KAAjB,CAAd;AACA,cAAQ,IAAR,CAAa,iBAAb;AACA,aAAO,OAAP;AACD;;;;;;kBA/EkB,S;;;;;;;;;;;;;;kBCRG,K;;AAPxB;;;;;;;;AAEA;AACA;AACA,OAAO,kBAAP,GAA4B,OAAO,kBAAP,IAA6B,EAAzD;AACA,IAAI,SAAS,OAAO,kBAApB;;AAEe,SAAS,KAAT,CAAe,SAAf,EAA0B;AACvC,MAAI,aAAa,OAAO,SAAP,KAAsB,QAAvC,EAAiD;AAC/C,QAAI,CAAC,OAAO,cAAP,CAAsB,SAAtB,CAAL,EAAuC;AACrC,aAAO,SAAP,IAAoB,IAAI,KAAJ,CAAU,SAAV,CAApB;AACD;AACD,WAAO,OAAO,SAAP,CAAP;AACD,GALD,MAKO,IAAI,QAAO,SAAP,yCAAO,SAAP,OAAsB,QAAtB,IAAkC,UAAU,KAA5C,IAAqD,UAAU,GAAnE,EAAwE;AAC7E;AACA,WAAO,SAAP;AACD,GAHM,MAGA,IAAI,MAAM,OAAN,CAAc,SAAd,KACP,UAAU,MAAV,IAAoB,CADb,IAEP,OAAO,UAAU,CAAV,CAAP,KAAyB,QAFtB,EAEgC;AACrC,WAAO,MAAM,UAAU,CAAV,CAAN,CAAP;AACD,GAJM,MAIA;AACL,UAAM,IAAI,KAAJ,CAAU,4BAAV,CAAN;AACD;AACF;;IAEK,K;AACJ,iBAAY,IAAZ,EAAkB;AAAA;;AAChB,SAAK,IAAL,GAAY,IAAZ;AACA,SAAK,KAAL,GAAa,EAAb;AACD;;;;yBAEG,I,EAAM;AACR,UAAI,CAAC,IAAD,IAAS,OAAO,IAAP,KAAiB,QAA9B,EAAwC;AACtC,cAAM,IAAI,KAAJ,CAAU,kBAAV,CAAN;AACD;;AAED,UAAI,CAAC,KAAK,KAAL,CAAW,cAAX,CAA0B,IAA1B,CAAL,EACE,KAAK,KAAL,CAAW,IAAX,IAAmB,kBAAQ,IAAR,EAAc,IAAd,CAAnB;AACF,aAAO,KAAK,KAAL,CAAW,IAAX,CAAP;AACD;;;wBAEG,I,EAAM;AACR,UAAI,CAAC,IAAD,IAAS,OAAO,IAAP,KAAiB,QAA9B,EAAwC;AACtC,cAAM,IAAI,KAAJ,CAAU,kBAAV,CAAN;AACD;;AAED,aAAO,KAAK,KAAL,CAAW,cAAX,CAA0B,IAA1B,CAAP;AACD;;;;;;;;;;;;;;;;AC/CH;;;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;;;AAEA,IAAM,eAAe,qBAAM,SAAN,CAArB;;AAEA,SAAS,IAAT,CAAc,IAAd,EAAoB;AAClB,SAAO,aAAa,GAAb,CAAiB,IAAjB,CAAP;AACD;;AAED,SAAS,GAAT,CAAa,IAAb,EAAmB;AACjB,SAAO,aAAa,GAAb,CAAiB,IAAjB,CAAP;AACD;;AAED,IAAI,OAAO,KAAX,EAAkB;AAChB,SAAO,KAAP,CAAa,uBAAb,CAAqC,qBAArC,EAA4D,UAAS,OAAT,EAAkB;AAC5E,QAAI,OAAO,QAAQ,KAAf,KAA0B,QAA9B,EAAwC;AACtC,2BAAM,QAAQ,KAAd,EAAqB,GAArB,CAAyB,QAAQ,IAAjC,EAAuC,GAAvC,CAA2C,QAAQ,KAAnD;AACD,KAFD,MAEO;AACL,WAAK,QAAQ,IAAb,EAAmB,GAAnB,CAAuB,QAAQ,KAA/B;AACD;AACF,GAND;AAOD;;AAED,IAAM,YAAY;AAChB,wBADgB;AAEhB,OAAK,IAFW;AAGhB,OAAK,GAHW;AAIhB,6CAJgB;AAKhB,oCALgB;AAMhB;AANgB,CAAlB;;AASA;;;kBAGe,S;;AACf,OAAO,SAAP,GAAmB,SAAnB;;;;;;;;;;;QCrCgB,Q,GAAA,Q;QAWA,I,GAAA,I;AAfhB,IAAI,IAAI,OAAO,MAAf;;AAEA,IAAI,WAAW,EAAf;;AAEO,SAAS,QAAT,CAAkB,GAAlB,EAAuB;AAC5B,WAAS,IAAI,SAAb,IAA0B,GAA1B;AACA,MAAI,OAAO,QAAP,IAAmB,OAAO,QAAP,CAAgB,UAAhB,KAA+B,UAAtD,EAAkE;AAChE,MAAE,YAAM;AACN;AACD,KAFD;AAGD,GAJD,MAIO,IAAI,OAAO,QAAX,EAAqB;AAC1B,eAAW,IAAX,EAAiB,GAAjB;AACD;AACF;;AAEM,SAAS,IAAT,GAAgB;AACrB,SAAO,IAAP,CAAY,QAAZ,EAAsB,OAAtB,CAA8B,UAAS,SAAT,EAAoB;AAChD,QAAI,UAAU,SAAS,SAAT,CAAd;AACA,MAAE,MAAM,QAAQ,SAAhB,EAA2B,GAA3B,CAA+B,wBAA/B,EAAyD,IAAzD,CAA8D,UAAS,CAAT,EAAY,EAAZ,EAAgB;AAC5E,mBAAa,OAAb,EAAsB,EAAtB;AACD,KAFD;AAGD,GALD;AAMD;;AAED;AACA,SAAS,OAAT,CAAiB,GAAjB,EAAsB;AACpB,SAAO,IAAI,OAAJ,CAAY,uCAAZ,EAAqD,MAArD,CAAP;AACD;;AAED,SAAS,MAAT,CAAgB,EAAhB,EAAoB;AAClB,MAAI,MAAM,EAAE,EAAF,CAAV;AACA,SAAO,IAAP,CAAY,QAAZ,EAAsB,OAAtB,CAA8B,UAAS,SAAT,EAAoB;AAChD,QAAI,IAAI,QAAJ,CAAa,SAAb,KAA2B,CAAC,IAAI,QAAJ,CAAa,uBAAb,CAAhC,EAAuE;AACrE,UAAI,UAAU,SAAS,SAAT,CAAd;AACA,mBAAa,OAAb,EAAsB,EAAtB;AACD;AACF,GALD;AAMD;;AAED,SAAS,YAAT,CAAsB,OAAtB,EAA+B,EAA/B,EAAmC;AACjC,MAAI,SAAS,EAAE,EAAF,EAAM,IAAN,CAAW,+CAA+C,QAAQ,GAAG,EAAX,CAA/C,GAAgE,IAA3E,CAAb;AACA,MAAI,OAAO,KAAK,KAAL,CAAW,OAAO,CAAP,EAAU,SAArB,CAAX;;AAEA,MAAI,WAAW,QAAQ,OAAR,CAAgB,EAAhB,EAAoB,IAApB,CAAf;AACA,IAAE,EAAF,EAAM,IAAN,CAAW,oBAAX,EAAiC,QAAjC;AACA,IAAE,EAAF,EAAM,QAAN,CAAe,uBAAf;AACD;;AAED,IAAI,OAAO,KAAX,EAAkB;AAChB,MAAI,eAAe,IAAI,OAAO,KAAP,CAAa,YAAjB,EAAnB;AACA,MAAI,KAAI,OAAO,MAAf;AACA,KAAE,MAAF,CAAS,YAAT,EAAuB;AACrB,UAAM,cAAS,KAAT,EAAgB;AACpB,aAAO,GAAE,KAAF,EAAS,IAAT,CAAc,kBAAd,CAAP;AACD,KAHoB;AAIrB,gBAAY,oBAAS,EAAT,EAAa;AACvB,UAAI,CAAC,GAAE,EAAF,EAAM,QAAN,CAAe,uBAAf,CAAL,EAA8C;AAC5C,eAAO,EAAP;AACD;AACF,KARoB;AASrB,WAAO,eAAS,EAAT,EAAa;AAClB,aAAO,GAAG,EAAV;AACD,KAXoB;AAYrB,cAAU,kBAAS,EAAT,EAAa,CAEtB,CAdoB;AAerB,cAAU,kBAAS,EAAT,EAAa,KAAb,EAAoB,CAE7B,CAjBoB;AAkBrB,oBAAgB,wBAAS,EAAT,EAAa,IAAb,EAAmB,CAElC,CApBoB;AAqBrB,eAAW,mBAAS,EAAT,EAAa,QAAb,EAAuB;AAChC,SAAE,EAAF,EAAM,IAAN,CAAW,oBAAX,EAAiC,MAAjC;AACD,KAvBoB;AAwBrB,iBAAa,qBAAS,EAAT,EAAa;AACxB,SAAE,EAAF,EAAM,IAAN,CAAW,oBAAX,EAAiC,OAAjC;AACD;AA1BoB,GAAvB;AA4BA,SAAO,KAAP,CAAa,aAAb,CAA2B,QAA3B,CAAoC,YAApC,EAAkD,wBAAlD;AACD;;;;;;;;AChFD;;IAAY,K;;AACZ;;;;AAEA,IAAI,IAAI,OAAO,MAAf;;AAEA,MAAM,QAAN,CAAe;AACb,aAAW,+BADE;;AAGb,WAAS,iBAAS,EAAT,EAAa,IAAb,EAAmB;AAC1B;;;;AAIA,QAAI,WAAW,yBAAiB,KAAK,KAAtB,CAAf;;AAEA,QAAI,sBAAJ;AACA,QAAI,MAAM,EAAE,EAAF,CAAV;AACA,QAAI,EAAJ,CAAO,QAAP,EAAiB,wBAAjB,EAA2C,YAAW;AACpD,UAAI,UAAU,IAAI,IAAJ,CAAS,gCAAT,CAAd;AACA,UAAI,QAAQ,MAAR,KAAmB,CAAvB,EAA0B;AACxB,wBAAgB,IAAhB;AACA,iBAAS,KAAT;AACD,OAHD,MAGO;AACL,YAAI,OAAO,EAAX;AACA,gBAAQ,IAAR,CAAa,YAAW;AACtB,eAAK,GAAL,CAAS,KAAK,KAAd,EAAqB,OAArB,CAA6B,UAAS,GAAT,EAAc;AACzC,iBAAK,GAAL,IAAY,IAAZ;AACD,WAFD;AAGD,SAJD;AAKA,YAAI,WAAW,OAAO,IAAP,CAAY,IAAZ,CAAf;AACA,iBAAS,IAAT;AACA,wBAAgB,QAAhB;AACA,iBAAS,GAAT,CAAa,QAAb;AACD;AACF,KAjBD;;AAmBA,WAAO;AACL,eAAS,mBAAW;AAClB,iBAAS,KAAT;AACD,OAHI;AAIL,cAAQ,kBAAW;AACjB,YAAI,aAAJ,EACE,SAAS,GAAT,CAAa,aAAb;AACH;AAPI,KAAP;AASD;AAxCY,CAAf;;;;;;;;ACLA;;IAAY,K;;AACZ;;IAAY,I;;AACZ;;;;AAEA,IAAI,IAAI,OAAO,MAAf;;AAEA,MAAM,QAAN,CAAe;AACb,aAAW,wBADE;;AAGb,WAAS,iBAAS,EAAT,EAAa,IAAb,EAAmB;AAC1B;;;;;;AAMA,QAAI,QAAQ,CAAC,EAAC,OAAO,EAAR,EAAY,OAAO,OAAnB,EAAD,CAAZ;AACA,QAAI,QAAQ,KAAK,aAAL,CAAmB,KAAK,KAAxB,CAAZ;AACA,QAAI,OAAO;AACT,eAAS,MAAM,MAAN,CAAa,KAAb,CADA;AAET,kBAAY,OAFH;AAGT,kBAAY,OAHH;AAIT,mBAAa;AAJJ,KAAX;;AAOA,QAAI,SAAS,EAAE,EAAF,EAAM,IAAN,CAAW,QAAX,EAAqB,CAArB,CAAb;;AAEA,QAAI,YAAY,EAAE,MAAF,EAAU,SAAV,CAAoB,IAApB,EAA0B,CAA1B,EAA6B,SAA7C;;AAEA,QAAI,WAAW,yBAAiB,KAAK,KAAtB,CAAf;;AAEA,QAAI,sBAAJ;AACA,cAAU,EAAV,CAAa,QAAb,EAAuB,YAAW;AAChC,UAAI,UAAU,KAAV,CAAgB,MAAhB,KAA2B,CAA/B,EAAkC;AAChC,wBAAgB,IAAhB;AACA,iBAAS,KAAT;AACD,OAHD,MAGO;AACL,YAAI,OAAO,EAAX;AACA,kBAAU,KAAV,CAAgB,OAAhB,CAAwB,UAAS,KAAT,EAAgB;AACtC,eAAK,GAAL,CAAS,KAAT,EAAgB,OAAhB,CAAwB,UAAS,GAAT,EAAc;AACpC,iBAAK,GAAL,IAAY,IAAZ;AACD,WAFD;AAGD,SAJD;AAKA,YAAI,WAAW,OAAO,IAAP,CAAY,IAAZ,CAAf;AACA,iBAAS,IAAT;AACA,wBAAgB,QAAhB;AACA,iBAAS,GAAT,CAAa,QAAb;AACD;AACF,KAhBD;;AAkBA,WAAO;AACL,eAAS,mBAAW;AAClB,iBAAS,KAAT;AACD,OAHI;AAIL,cAAQ,kBAAW;AACjB,YAAI,aAAJ,EACE,SAAS,GAAT,CAAa,aAAb;AACH;AAPI,KAAP;AASD;AArDY,CAAf;;;;;;;;;;ACNA;;IAAY,K;;AACZ;;;;AAEA,IAAI,IAAI,OAAO,MAAf;AACA,IAAI,WAAW,OAAO,QAAtB;;AAEA,MAAM,QAAN,CAAe;AACb,aAAW,wBADE;;AAGb,WAAS,iBAAS,EAAT,EAAa,IAAb,EAAmB;AAC1B;;;;AAIA,QAAI,WAAW,yBAAiB,KAAK,KAAtB,CAAf;;AAEA,QAAI,OAAO,EAAX;AACA,QAAI,MAAM,EAAE,EAAF,EAAM,IAAN,CAAW,OAAX,CAAV;AACA,QAAI,WAAW,IAAI,IAAJ,CAAS,WAAT,CAAf;AACA,QAAI,aAAa,IAAI,IAAJ,CAAS,aAAT,CAAjB;AACA,QAAI,QAAQ,IAAI,IAAJ,CAAS,OAAT,CAAZ;AACA,QAAI,sBAAJ;;AAEA;AACA,QAAI,aAAa,MAAjB,EAAyB;AACvB,sBAAgB,SAAS,GAAT,EAAhB;AACA,WAAK,QAAL,GAAgB,UAAS,GAAT,EAAc;AAC5B,eAAO,cAAc,UAAd,EAA0B,IAAI,IAAJ,CAAS,GAAT,CAA1B,CAAP;AACD,OAFD;AAID,KAND,MAMO,IAAI,aAAa,UAAjB,EAA6B;AAClC,UAAI,WAAW,IAAI,IAAJ,CAAS,UAAT,CAAf;AACA,UAAI,QAAJ,EACE,gBAAgB,SAAS,QAAT,CAAkB,QAAlB,CAAhB,CADF,KAGE,gBAAgB,QAAhB;;AAEF,WAAK,QAAL,GAAgB,UAAS,GAAT,EAAc;AAC5B,eAAO,cAAc,UAAd,EAA0B,IAAI,IAAJ,CAAS,GAAT,CAA1B,CAAP;AACD,OAFD;AAGD,KAVM,MAUA,IAAI,aAAa,QAAjB,EAA2B;AAChC,UAAI,OAAO,KAAP,KAAiB,WAArB,EACE,KAAK,QAAL,GAAgB,UAAS,GAAT,EAAc;AAC5B,YAAI,SAAS,KAAK,GAAL,CAAS,EAAT,EAAa,KAAb,CAAb;AACA,eAAO,KAAK,KAAL,CAAW,MAAM,MAAjB,IAA2B,MAAlC;AACD,OAHD;AAIH;;AAED,QAAI,cAAJ,CAAmB,IAAnB;;AAEA,aAAS,QAAT,GAAoB;AAClB,UAAI,SAAS,IAAI,IAAJ,CAAS,gBAAT,EAA2B,MAAxC;;AAEA;AACA,UAAI,gBAAJ;AACA,UAAI,WAAW,IAAI,IAAJ,CAAS,WAAT,CAAf;AACA,UAAI,aAAa,MAAjB,EAAyB;AACvB,kBAAU,iBAAS,GAAT,EAAc;AACtB,iBAAO,cAAc,IAAI,IAAJ,CAAS,CAAC,GAAV,CAAd,CAAP;AACD,SAFD;AAGD,OAJD,MAIO,IAAI,aAAa,UAAjB,EAA6B;AAClC,kBAAU,iBAAS,GAAT,EAAc;AACtB;AACA,iBAAO,CAAC,GAAD,GAAO,IAAd;AACD,SAHD;AAID,OALM,MAKA;AACL,kBAAU,iBAAS,GAAT,EAAc;AAAE,iBAAO,CAAC,GAAR;AAAc,SAAxC;AACD;;AAED,UAAI,IAAI,IAAJ,CAAS,gBAAT,EAA2B,OAA3B,CAAmC,IAAnC,KAA4C,QAAhD,EAA0D;AACxD,eAAO,CAAC,QAAQ,OAAO,IAAf,CAAD,EAAuB,QAAQ,OAAO,EAAf,CAAvB,CAAP;AACD,OAFD,MAEO;AACL,eAAO,QAAQ,OAAO,IAAf,CAAP;AACD;AACF;;AAED,QAAI,gBAAgB,IAApB;;AAEA,QAAI,EAAJ,CAAO,6BAAP,EAAsC,UAAS,KAAT,EAAgB;AACpD,UAAI,CAAC,IAAI,IAAJ,CAAS,UAAT,CAAD,IAAyB,CAAC,IAAI,IAAJ,CAAS,WAAT,CAA9B,EAAqD;AAAA,wBAClC,UADkC;AAAA;AAAA,YAC9C,IAD8C;AAAA,YACxC,EADwC;;AAEnD,YAAI,OAAO,EAAX;AACA,aAAK,IAAI,IAAI,CAAb,EAAgB,IAAI,KAAK,MAAL,CAAY,MAAhC,EAAwC,GAAxC,EAA6C;AAC3C,cAAI,MAAM,KAAK,MAAL,CAAY,CAAZ,CAAV;AACA,cAAI,OAAO,IAAP,IAAe,OAAO,EAA1B,EAA8B;AAC5B,iBAAK,IAAL,CAAU,KAAK,IAAL,CAAU,CAAV,CAAV;AACD;AACF;AACD,aAAK,IAAL;AACA,iBAAS,GAAT,CAAa,IAAb;AACA,wBAAgB,IAAhB;AACD;AACF,KAdD;;AAiBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,WAAO;AACL,eAAS,mBAAW;AAClB,iBAAS,KAAT;AACD,OAHI;AAIL,cAAQ,kBAAW;AACjB,YAAI,aAAJ,EACE,SAAS,GAAT,CAAa,aAAb;AACH;AAPI,KAAP;AASD;AApHY,CAAf;;AAwHA;AACA,SAAS,QAAT,CAAkB,CAAlB,EAAqB,MAArB,EAA6B;AAC3B,MAAI,MAAM,EAAE,QAAF,EAAV;AACA,SAAO,IAAI,MAAJ,GAAa,MAApB;AACE,UAAM,MAAM,GAAZ;AADF,GAEA,OAAO,GAAP;AACD;;AAED;AACA;AACA,SAAS,aAAT,CAAuB,IAAvB,EAA6B;AAC3B,MAAI,gBAAgB,IAApB,EAA0B;AACxB,WAAO,KAAK,cAAL,KAAwB,GAAxB,GACA,SAAS,KAAK,WAAL,KAAmB,CAA5B,EAA+B,CAA/B,CADA,GACoC,GADpC,GAEA,SAAS,KAAK,UAAL,EAAT,EAA4B,CAA5B,CAFP;AAID,GALD,MAKO;AACL,WAAO,IAAP;AACD;AACF;;;;;;;;;;;;;;ACjJD;;;;AACA;;;;AACA;;IAAY,I;;;;;;;;AAEZ;;;;;;;;;;;;;;;;IAgBa,e,WAAA,e;AAEX,6BAA4C;AAAA,QAAhC,KAAgC,uEAAxB,IAAwB;AAAA,QAAlB,SAAkB,uEAAN,IAAM;;AAAA;;AAC1C,SAAK,WAAL,GAAmB,sBAAnB;AACA,SAAK,QAAL,GAAgB,IAAI,KAAK,mBAAT,CAA6B,KAAK,WAAlC,CAAhB;;AAEA;AACA,SAAK,MAAL,GAAc,IAAd;AACA;AACA,SAAK,IAAL,GAAY,IAAZ;AACA;AACA,SAAK,eAAL,GAAuB,IAAvB;;AAEA,SAAK,UAAL,GAAkB,KAAK,MAAL,CAAY,EAAE,QAAQ,IAAV,EAAZ,EAA8B,SAA9B,CAAlB;;AAEA,SAAK,QAAL,CAAc,KAAd;AACD;;AAED;;;;;;;;;;;;;;;;;6BAaS,K,EAAO;AAAA;;AACd;AACA,UAAI,KAAK,MAAL,KAAgB,KAApB,EACE;AACF;AACA,UAAI,CAAC,KAAK,MAAN,IAAgB,CAAC,KAArB,EACE;;AAEF,UAAI,KAAK,IAAT,EAAe;AACb,aAAK,IAAL,CAAU,GAAV,CAAc,QAAd,EAAwB,KAAK,eAA7B;AACA,aAAK,IAAL,GAAY,IAAZ;AACA,aAAK,eAAL,GAAuB,IAAvB;AACD;;AAED,WAAK,MAAL,GAAc,KAAd;;AAEA,UAAI,KAAJ,EAAW;AACT,aAAK,IAAL,GAAY,qBAAI,KAAJ,EAAW,GAAX,CAAe,WAAf,CAAZ;AACA,YAAI,MAAM,KAAK,IAAL,CAAU,EAAV,CAAa,QAAb,EAAuB,UAAC,CAAD,EAAO;AACtC,gBAAK,WAAL,CAAiB,OAAjB,CAAyB,QAAzB,EAAmC,CAAnC;AACD,SAFS,CAAV;AAGA,aAAK,eAAL,GAAuB,GAAvB;AACD;AACF;;AAED;;;;;;;;;;;;;;;AAcA;;;;;oCAKgB,S,EAAW;AACzB;AACA,aAAO,KAAK,MAAL,CAAY,EAAZ,EACL,KAAK,UAAL,GAAkB,KAAK,UAAvB,GAAoC,IAD/B,EAEL,YAAY,SAAZ,GAAwB,IAFnB,CAAP;AAGD;;AAED;;;;;;;;;;;;;;;wBAYI,Y,EAAc,S,EAAW;AAC3B,UAAI,KAAK,IAAT,EACE,KAAK,IAAL,CAAU,GAAV,CAAc,YAAd,EAA4B,KAAK,eAAL,CAAqB,SAArB,CAA5B;AACH;;AAED;;;;;;;;;;;;;0BAUM,S,EAAW;AACf,UAAI,KAAK,IAAT,EACE,KAAK,GAAL,CAAS,KAAK,CAAd,EAAiB,KAAK,eAAL,CAAqB,SAArB,CAAjB;AACH;;AAED;;;;;;;;;;;;;uBAUG,S,EAAW,Q,EAAU;AACtB,aAAO,KAAK,QAAL,CAAc,EAAd,CAAiB,SAAjB,EAA4B,QAA5B,CAAP;AACD;;AAED;;;;;;;;;;;wBAQI,S,EAAW,Q,EAAU;AACvB,aAAO,KAAK,QAAL,CAAc,GAAd,CAAkB,SAAlB,EAA6B,QAA7B,CAAP;AACD;;AAED;;;;;;;;4BAKQ;AACN,WAAK,QAAL,CAAc,kBAAd;AACA,WAAK,QAAL,CAAc,IAAd;AACD;;;wBAlFW;AACV,aAAO,KAAK,IAAL,GAAY,KAAK,IAAL,CAAU,GAAV,EAAZ,GAA8B,IAArC;AACD;;;;;;AAmFH;;;;;;;;;AASA;;;;;;;;;;;;;;;;;;;;;QCpLgB,M,GAAA,M;QAeA,W,GAAA,W;QAQA,e,GAAA,e;QAoCA,a,GAAA,a;;;;AA3DT,SAAS,MAAT,CAAgB,MAAhB,EAAoC;AAAA,oCAAT,OAAS;AAAT,WAAS;AAAA;;AACzC,OAAK,IAAI,IAAI,CAAb,EAAgB,IAAI,QAAQ,MAA5B,EAAoC,GAApC,EAAyC;AACvC,QAAI,MAAM,QAAQ,CAAR,CAAV;AACA,QAAI,OAAO,GAAP,KAAgB,WAAhB,IAA+B,QAAQ,IAA3C,EACE;;AAEF,SAAK,IAAI,GAAT,IAAgB,GAAhB,EAAqB;AACnB,UAAI,IAAI,cAAJ,CAAmB,GAAnB,CAAJ,EAA6B;AAC3B,eAAO,GAAP,IAAc,IAAI,GAAJ,CAAd;AACD;AACF;AACF;AACD,SAAO,MAAP;AACD;;AAEM,SAAS,WAAT,CAAqB,IAArB,EAA2B;AAChC,OAAK,IAAI,IAAI,CAAb,EAAgB,IAAI,KAAK,MAAzB,EAAiC,GAAjC,EAAsC;AACpC,QAAI,KAAK,CAAL,KAAW,KAAK,IAAE,CAAP,CAAf,EAA0B;AACxB,YAAM,IAAI,KAAJ,CAAU,0CAAV,CAAN;AACD;AACF;AACF;;AAEM,SAAS,eAAT,CAAyB,CAAzB,EAA4B,CAA5B,EAA+B;AACpC,MAAI,MAAM,CAAV;AACA,MAAI,MAAM,CAAV;;AAEA,MAAI,CAAC,CAAL,EAAQ,IAAI,EAAJ;AACR,MAAI,CAAC,CAAL,EAAQ,IAAI,EAAJ;;AAER,MAAI,SAAS,EAAb;AACA,MAAI,SAAS,EAAb;;AAEA,cAAY,CAAZ;AACA,cAAY,CAAZ;;AAEA,SAAO,MAAM,EAAE,MAAR,IAAkB,MAAM,EAAE,MAAjC,EAAyC;AACvC,QAAI,EAAE,GAAF,MAAW,EAAE,GAAF,CAAf,EAAuB;AACrB;AACA;AACD,KAHD,MAGO,IAAI,EAAE,GAAF,IAAS,EAAE,GAAF,CAAb,EAAqB;AAC1B,aAAO,IAAP,CAAY,EAAE,KAAF,CAAZ;AACD,KAFM,MAEA;AACL,aAAO,IAAP,CAAY,EAAE,KAAF,CAAZ;AACD;AACF;;AAED,MAAI,MAAM,EAAE,MAAZ,EACE,SAAS,OAAO,MAAP,CAAc,EAAE,KAAF,CAAQ,GAAR,CAAd,CAAT;AACF,MAAI,MAAM,EAAE,MAAZ,EACE,SAAS,OAAO,MAAP,CAAc,EAAE,KAAF,CAAQ,GAAR,CAAd,CAAT;AACF,SAAO;AACL,aAAS,MADJ;AAEL,WAAO;AAFF,GAAP;AAID;;AAED;AACA;AACO,SAAS,aAAT,CAAuB,EAAvB,EAA2B;AAChC,MAAI,QAAQ,EAAZ;AACA,MAAI,eAAJ;AACA,OAAK,IAAI,IAAT,IAAiB,EAAjB,EAAqB;AACnB,QAAI,GAAG,cAAH,CAAkB,IAAlB,CAAJ,EACE,MAAM,IAAN,CAAW,IAAX;AACF,QAAI,QAAO,GAAG,IAAH,CAAP,MAAqB,QAArB,IAAiC,OAAO,GAAG,IAAH,EAAS,MAAhB,KAA4B,WAAjE,EAA8E;AAC5E,YAAM,IAAI,KAAJ,CAAU,2BAAV,CAAN;AACD,KAFD,MAEO,IAAI,OAAO,MAAP,KAAmB,WAAnB,IAAkC,WAAW,GAAG,IAAH,EAAS,MAA1D,EAAkE;AACvE,YAAM,IAAI,KAAJ,CAAU,8CAAV,CAAN;AACD;AACD,aAAS,GAAG,IAAH,EAAS,MAAlB;AACD;AACD,MAAI,UAAU,EAAd;AACA,MAAI,aAAJ;AACA,OAAK,IAAI,MAAM,CAAf,EAAkB,MAAM,MAAxB,EAAgC,KAAhC,EAAuC;AACrC,WAAO,EAAP;AACA,SAAK,IAAI,MAAM,CAAf,EAAkB,MAAM,MAAM,MAA9B,EAAsC,KAAtC,EAA6C;AAC3C,WAAK,MAAM,GAAN,CAAL,IAAmB,GAAG,MAAM,GAAN,CAAH,EAAe,GAAf,CAAnB;AACD;AACD,YAAQ,IAAR,CAAa,IAAb;AACD;AACD,SAAO,OAAP;AACD;;AAED;;;;;;;IAMa,mB,WAAA,mB;AACX,+BAAY,OAAZ,EAAqB;AAAA;;AACnB,SAAK,QAAL,GAAgB,OAAhB;AACA,SAAK,KAAL,GAAa,EAAb;AACD;;;;uBAEE,S,EAAW,Q,EAAU;AACtB,UAAI,MAAM,KAAK,QAAL,CAAc,EAAd,CAAiB,SAAjB,EAA4B,QAA5B,CAAV;AACA,WAAK,KAAL,CAAW,GAAX,IAAkB,SAAlB;AACA,aAAO,GAAP;AACD;;;wBAEG,S,EAAW,Q,EAAU;AACvB,UAAI,MAAM,KAAK,QAAL,CAAc,GAAd,CAAkB,SAAlB,EAA6B,QAA7B,CAAV;AACA,UAAI,GAAJ,EAAS;AACP,eAAO,KAAK,KAAL,CAAW,GAAX,CAAP;AACD;AACD,aAAO,GAAP;AACD;;;yCAEoB;AAAA;;AACnB,UAAI,eAAe,KAAK,KAAxB;AACA,WAAK,KAAL,GAAa,EAAb;AACA,aAAO,IAAP,CAAY,YAAZ,EAA0B,OAA1B,CAAkC,UAAC,GAAD,EAAS;AACzC,cAAK,QAAL,CAAc,GAAd,CAAkB,aAAa,GAAb,CAAlB,EAAqC,GAArC;AACD,OAFD;AAGD;;;;;;;;;;;;;;;;;;ACpHH;;;;;;;;IAEqB,G;AACnB,eAAY,KAAZ,EAAmB,IAAnB,EAAyB,YAAa,KAAtC,EAA6C;AAAA;;AAC3C,SAAK,MAAL,GAAc,KAAd;AACA,SAAK,KAAL,GAAa,IAAb;AACA,SAAK,MAAL,GAAc,KAAd;AACA,SAAK,OAAL,GAAe,sBAAf;AACD;;;;0BAEK;AACJ,aAAO,KAAK,MAAZ;AACD;;;wBAEG,K,EAAO,YAAa,K,EAAO;AAC7B,UAAI,KAAK,MAAL,KAAgB,KAApB,EAA2B;AACzB;AACA;AACD;AACD,UAAI,WAAW,KAAK,MAApB;AACA,WAAK,MAAL,GAAc,KAAd;AACA;AACA,UAAI,MAAM,EAAV;AACA,UAAI,SAAS,QAAO,KAAP,yCAAO,KAAP,OAAkB,QAA/B,EAAyC;AACvC,aAAK,IAAI,CAAT,IAAc,KAAd,EAAqB;AACnB,cAAI,MAAM,cAAN,CAAqB,CAArB,CAAJ,EACE,IAAI,CAAJ,IAAS,MAAM,CAAN,CAAT;AACH;AACF;AACD,UAAI,QAAJ,GAAe,QAAf;AACA,UAAI,KAAJ,GAAY,KAAZ;AACA,WAAK,OAAL,CAAa,OAAb,CAAqB,QAArB,EAA+B,GAA/B,EAAoC,IAApC;;AAEA;AACA;AACA,UAAI,OAAO,KAAP,IAAgB,OAAO,KAAP,CAAa,aAAjC,EAAgD;AAC9C,eAAO,KAAP,CAAa,aAAb,CACE,mBACG,KAAK,MAAL,CAAY,IAAZ,KAAqB,IAArB,GAA4B,KAAK,MAAL,CAAY,IAAZ,GAAmB,GAA/C,GAAqD,EADxD,IAEE,KAAK,KAHT,EAIE,OAAO,KAAP,KAAkB,WAAlB,GAAgC,IAAhC,GAAuC,KAJzC;AAMD;AACF;;;uBAEE,S,EAAW,Q,EAAU;AACtB,aAAO,KAAK,OAAL,CAAa,EAAb,CAAgB,SAAhB,EAA2B,QAA3B,CAAP;AACD;;;wBAEG,S,EAAW,Q,EAAU;AACvB,aAAO,KAAK,OAAL,CAAa,GAAb,CAAiB,SAAjB,EAA4B,QAA5B,CAAP;AACD;;;;;;kBAjDkB,G", + "file": "generated.js", + "sourceRoot": "", + "sourcesContent": [ + "(function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o {\n this._eventRelay.trigger(\"change\", e, this);\n });\n this._varOnChangeSub = sub;\n }\n }\n\n /**\n * Combine the given `extraInfo` (if any) with the handle's default\n * `_extraInfo` (if any).\n * @private\n */\n _mergeExtraInfo(extraInfo) {\n return util.extend({},\n this._extraInfo ? this._extraInfo : null,\n extraInfo ? extraInfo : null);\n }\n\n /**\n * Close the handle. This clears this handle's contribution to the filter set,\n * and unsubscribes all event listeners.\n */\n close() {\n this._emitter.removeAllListeners();\n this.clear();\n this.setGroup(null);\n }\n\n /**\n * Clear this handle's contribution to the filter set.\n *\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any options that were\n * passed into the `FilterHandle` constructor).\n * \n * @fires FilterHandle#change\n */\n clear(extraInfo) {\n if (!this._filterSet)\n return;\n this._filterSet.clear(this._id);\n this._onChange(extraInfo);\n }\n\n /**\n * Set this handle's contribution to the filter set. This array should consist\n * of the keys of the rows that _should_ be displayed; any keys that are not\n * present in the array will be considered _filtered out_. Note that multiple\n * `FilterHandle` instances in the group may each contribute an array of keys,\n * and only those keys that appear in _all_ of the arrays make it through the\n * filter.\n *\n * @param {string[]} keys - Empty array, or array of keys. To clear the\n * filter, don't pass an empty array; instead, use the\n * {@link FilterHandle#clear} method.\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any options that were\n * passed into the `FilterHandle` constructor).\n * \n * @fires FilterHandle#change\n */\n set(keys, extraInfo) {\n if (!this._filterSet)\n return;\n this._filterSet.update(this._id, keys);\n this._onChange(extraInfo);\n }\n\n /**\n * @return {string[]|null} - Either: 1) an array of keys that made it through\n * all of the `FilterHandle` instances, or, 2) `null`, which means no filter\n * is being applied (all data should be displayed).\n */\n get filteredKeys() {\n return this._filterSet ? this._filterSet.value : null;\n }\n\n /**\n * Subscribe to events on this `FilterHandle`.\n *\n * @param {string} eventType - Indicates the type of events to listen to.\n * Currently, only `\"change\"` is supported.\n * @param {FilterHandle~listener} listener - The callback function that\n * will be invoked when the event occurs.\n * @return {string} - A token to pass to {@link FilterHandle#off} to cancel\n * this subscription.\n */\n on(eventType, listener) {\n return this._emitter.on(eventType, listener);\n }\n\n /**\n * Cancel event subscriptions created by {@link FilterHandle#on}.\n *\n * @param {string} eventType - The type of event to unsubscribe.\n * @param {string|FilterHandle~listener} listener - Either the callback\n * function previously passed into {@link FilterHandle#on}, or the\n * string that was returned from {@link FilterHandle#on}.\n */\n off(eventType, listener) {\n return this._emitter.off(eventType, listener);\n }\n\n _onChange(extraInfo) {\n if (!this._filterSet)\n return;\n this._filterVar.set(this._filterSet.value, this._mergeExtraInfo(extraInfo));\n }\n\n /**\n * @callback FilterHandle~listener\n * @param {Object} event - An object containing details of the event. For\n * `\"change\"` events, this includes the properties `value` (the new\n * value of the filter set, or `null` if no filter set is active),\n * `oldValue` (the previous value of the filter set), and `sender` (the\n * `FilterHandle` instance that made the change).\n */\n\n}\n\n/**\n * @event FilterHandle#change\n * @type {object}\n * @property {object} value - The new value of the filter set, or `null`\n * if no filter set is active.\n * @property {object} oldValue - The previous value of the filter set.\n * @property {FilterHandle} sender - The `FilterHandle` instance that\n * changed the value.\n */\n", + "import { diffSortedLists } from \"./util\";\n\nfunction naturalComparator(a, b) {\n if (a === b) {\n return 0;\n } else if (a < b) {\n return -1;\n } else if (a > b) {\n return 1;\n }\n}\n\n/**\n * @private\n */\nexport default class FilterSet {\n constructor() {\n this.reset();\n }\n\n reset() {\n // Key: handle ID, Value: array of selected keys, or null\n this._handles = {};\n // Key: key string, Value: count of handles that include it\n this._keys = {};\n this._value = null;\n this._activeHandles = 0;\n }\n\n get value() {\n return this._value;\n }\n\n update(handleId, keys) {\n if (keys !== null) {\n keys = keys.slice(0); // clone before sorting\n keys.sort(naturalComparator);\n }\n\n let {added, removed} = diffSortedLists(this._handles[handleId], keys);\n this._handles[handleId] = keys;\n\n for (let i = 0; i < added.length; i++) {\n this._keys[added[i]] = (this._keys[added[i]] || 0) + 1;\n }\n for (let i = 0; i < removed.length; i++) {\n this._keys[removed[i]]--;\n }\n\n this._updateValue(keys);\n }\n\n /**\n * @param {string[]} keys Sorted array of strings that indicate\n * a superset of possible keys.\n * @private\n */\n _updateValue(keys = this._allKeys) {\n let handleCount = Object.keys(this._handles).length;\n if (handleCount === 0) {\n this._value = null;\n } else {\n this._value = [];\n for (let i = 0; i < keys.length; i++) {\n let count = this._keys[keys[i]];\n if (count === handleCount) {\n this._value.push(keys[i]);\n }\n }\n }\n }\n\n clear(handleId) {\n if (typeof(this._handles[handleId]) === \"undefined\") {\n return;\n }\n\n let keys = this._handles[handleId];\n if (!keys) {\n keys = [];\n }\n\n for (let i = 0; i < keys.length; i++) {\n this._keys[keys[i]]--;\n }\n delete this._handles[handleId];\n\n this._updateValue();\n }\n\n get _allKeys() {\n let allKeys = Object.keys(this._keys);\n allKeys.sort(naturalComparator);\n return allKeys;\n }\n}\n", + "import Var from \"./var\";\n\n// Use a global so that multiple copies of crosstalk.js can be loaded and still\n// have groups behave as singletons across all copies.\nglobal.__crosstalk_groups = global.__crosstalk_groups || {};\nlet groups = global.__crosstalk_groups;\n\nexport default function group(groupName) {\n if (groupName && typeof(groupName) === \"string\") {\n if (!groups.hasOwnProperty(groupName)) {\n groups[groupName] = new Group(groupName);\n }\n return groups[groupName];\n } else if (typeof(groupName) === \"object\" && groupName._vars && groupName.var) {\n // Appears to already be a group object\n return groupName;\n } else if (Array.isArray(groupName) &&\n groupName.length == 1 &&\n typeof(groupName[0]) === \"string\") {\n return group(groupName[0]);\n } else {\n throw new Error(\"Invalid groupName argument\");\n }\n}\n\nclass Group {\n constructor(name) {\n this.name = name;\n this._vars = {};\n }\n\n var(name) {\n if (!name || typeof(name) !== \"string\") {\n throw new Error(\"Invalid var name\");\n }\n\n if (!this._vars.hasOwnProperty(name))\n this._vars[name] = new Var(this, name);\n return this._vars[name];\n }\n\n has(name) {\n if (!name || typeof(name) !== \"string\") {\n throw new Error(\"Invalid var name\");\n }\n\n return this._vars.hasOwnProperty(name);\n }\n}\n", + "import group from \"./group\";\nimport { SelectionHandle } from \"./selection\";\nimport { FilterHandle } from \"./filter\";\nimport { bind } from \"./input\";\nimport \"./input_selectize\";\nimport \"./input_checkboxgroup\";\nimport \"./input_slider\";\n\nconst defaultGroup = group(\"default\");\n\nfunction var_(name) {\n return defaultGroup.var(name);\n}\n\nfunction has(name) {\n return defaultGroup.has(name);\n}\n\nif (global.Shiny) {\n global.Shiny.addCustomMessageHandler(\"update-client-value\", function(message) {\n if (typeof(message.group) === \"string\") {\n group(message.group).var(message.name).set(message.value);\n } else {\n var_(message.name).set(message.value);\n }\n });\n}\n\nconst crosstalk = {\n group: group,\n var: var_,\n has: has,\n SelectionHandle: SelectionHandle,\n FilterHandle: FilterHandle,\n bind: bind\n};\n\n/**\n * @namespace crosstalk\n */\nexport default crosstalk;\nglobal.crosstalk = crosstalk;\n", + "let $ = global.jQuery;\n\nlet bindings = {};\n\nexport function register(reg) {\n bindings[reg.className] = reg;\n if (global.document && global.document.readyState !== \"complete\") {\n $(() => {\n bind();\n });\n } else if (global.document) {\n setTimeout(bind, 100);\n }\n}\n\nexport function bind() {\n Object.keys(bindings).forEach(function(className) {\n let binding = bindings[className];\n $(\".\" + binding.className).not(\".crosstalk-input-bound\").each(function(i, el) {\n bindInstance(binding, el);\n });\n });\n}\n\n// Escape jQuery identifier\nfunction $escape(val) {\n return val.replace(/([!\"#$%&'()*+,./:;<=>?@[\\\\\\]^`{|}~])/g, \"\\\\$1\");\n}\n\nfunction bindEl(el) {\n let $el = $(el);\n Object.keys(bindings).forEach(function(className) {\n if ($el.hasClass(className) && !$el.hasClass(\"crosstalk-input-bound\")) {\n let binding = bindings[className];\n bindInstance(binding, el);\n }\n });\n}\n\nfunction bindInstance(binding, el) {\n let jsonEl = $(el).find(\"script[type='application/json'][data-for='\" + $escape(el.id) + \"']\");\n let data = JSON.parse(jsonEl[0].innerText);\n\n let instance = binding.factory(el, data);\n $(el).data(\"crosstalk-instance\", instance);\n $(el).addClass(\"crosstalk-input-bound\");\n}\n\nif (global.Shiny) {\n let inputBinding = new global.Shiny.InputBinding();\n let $ = global.jQuery;\n $.extend(inputBinding, {\n find: function(scope) {\n return $(scope).find(\".crosstalk-input\");\n },\n initialize: function(el) {\n if (!$(el).hasClass(\"crosstalk-input-bound\")) {\n bindEl(el);\n }\n },\n getId: function(el) {\n return el.id;\n },\n getValue: function(el) {\n\n },\n setValue: function(el, value) {\n\n },\n receiveMessage: function(el, data) {\n\n },\n subscribe: function(el, callback) {\n $(el).data(\"crosstalk-instance\").resume();\n },\n unsubscribe: function(el) {\n $(el).data(\"crosstalk-instance\").suspend();\n }\n });\n global.Shiny.inputBindings.register(inputBinding, \"crosstalk.inputBinding\");\n}\n", + "import * as input from \"./input\";\nimport { FilterHandle } from \"./filter\";\n\nlet $ = global.jQuery;\n\ninput.register({\n className: \"crosstalk-input-checkboxgroup\",\n\n factory: function(el, data) {\n /*\n * map: {\"groupA\": [\"keyA\", \"keyB\", ...], ...}\n * group: \"ct-groupname\"\n */\n let ctHandle = new FilterHandle(data.group);\n\n let lastKnownKeys;\n let $el = $(el);\n $el.on(\"change\", \"input[type='checkbox']\", function() {\n let checked = $el.find(\"input[type='checkbox']:checked\");\n if (checked.length === 0) {\n lastKnownKeys = null;\n ctHandle.clear();\n } else {\n let keys = {};\n checked.each(function() {\n data.map[this.value].forEach(function(key) {\n keys[key] = true;\n });\n });\n let keyArray = Object.keys(keys);\n keyArray.sort();\n lastKnownKeys = keyArray;\n ctHandle.set(keyArray);\n }\n });\n\n return {\n suspend: function() {\n ctHandle.clear();\n },\n resume: function() {\n if (lastKnownKeys)\n ctHandle.set(lastKnownKeys);\n }\n };\n }\n});\n", + "import * as input from \"./input\";\nimport * as util from \"./util\";\nimport { FilterHandle } from \"./filter\";\n\nlet $ = global.jQuery;\n\ninput.register({\n className: \"crosstalk-input-select\",\n\n factory: function(el, data) {\n /*\n * items: {value: [...], label: [...]}\n * map: {\"groupA\": [\"keyA\", \"keyB\", ...], ...}\n * group: \"ct-groupname\"\n */\n\n let first = [{value: \"\", label: \"(All)\"}];\n let items = util.dataframeToD3(data.items);\n let opts = {\n options: first.concat(items),\n valueField: \"value\",\n labelField: \"label\",\n searchField: \"label\"\n };\n\n let select = $(el).find(\"select\")[0];\n\n let selectize = $(select).selectize(opts)[0].selectize;\n\n let ctHandle = new FilterHandle(data.group);\n\n let lastKnownKeys;\n selectize.on(\"change\", function() {\n if (selectize.items.length === 0) {\n lastKnownKeys = null;\n ctHandle.clear();\n } else {\n let keys = {};\n selectize.items.forEach(function(group) {\n data.map[group].forEach(function(key) {\n keys[key] = true;\n });\n });\n let keyArray = Object.keys(keys);\n keyArray.sort();\n lastKnownKeys = keyArray;\n ctHandle.set(keyArray);\n }\n });\n\n return {\n suspend: function() {\n ctHandle.clear();\n },\n resume: function() {\n if (lastKnownKeys)\n ctHandle.set(lastKnownKeys);\n }\n };\n }\n});\n", + "import * as input from \"./input\";\nimport { FilterHandle } from \"./filter\";\n\nlet $ = global.jQuery;\nlet strftime = global.strftime;\n\ninput.register({\n className: \"crosstalk-input-slider\",\n\n factory: function(el, data) {\n /*\n * map: {\"groupA\": [\"keyA\", \"keyB\", ...], ...}\n * group: \"ct-groupname\"\n */\n let ctHandle = new FilterHandle(data.group);\n\n let opts = {};\n let $el = $(el).find(\"input\");\n let dataType = $el.data(\"data-type\");\n let timeFormat = $el.data(\"time-format\");\n let round = $el.data(\"round\");\n let timeFormatter;\n\n // Set up formatting functions\n if (dataType === \"date\") {\n timeFormatter = strftime.utc();\n opts.prettify = function(num) {\n return timeFormatter(timeFormat, new Date(num));\n };\n\n } else if (dataType === \"datetime\") {\n let timezone = $el.data(\"timezone\");\n if (timezone)\n timeFormatter = strftime.timezone(timezone);\n else\n timeFormatter = strftime;\n\n opts.prettify = function(num) {\n return timeFormatter(timeFormat, new Date(num));\n };\n } else if (dataType === \"number\") {\n if (typeof round !== \"undefined\")\n opts.prettify = function(num) {\n let factor = Math.pow(10, round);\n return Math.round(num * factor) / factor;\n };\n }\n\n $el.ionRangeSlider(opts);\n\n function getValue() {\n let result = $el.data(\"ionRangeSlider\").result;\n\n // Function for converting numeric value from slider to appropriate type.\n let convert;\n let dataType = $el.data(\"data-type\");\n if (dataType === \"date\") {\n convert = function(val) {\n return formatDateUTC(new Date(+val));\n };\n } else if (dataType === \"datetime\") {\n convert = function(val) {\n // Convert ms to s\n return +val / 1000;\n };\n } else {\n convert = function(val) { return +val; };\n }\n\n if ($el.data(\"ionRangeSlider\").options.type === \"double\") {\n return [convert(result.from), convert(result.to)];\n } else {\n return convert(result.from);\n }\n }\n\n let lastKnownKeys = null;\n\n $el.on(\"change.crosstalkSliderInput\", function(event) {\n if (!$el.data(\"updating\") && !$el.data(\"animating\")) {\n let [from, to] = getValue();\n let keys = [];\n for (let i = 0; i < data.values.length; i++) {\n let val = data.values[i];\n if (val >= from && val <= to) {\n keys.push(data.keys[i]);\n }\n }\n keys.sort();\n ctHandle.set(keys);\n lastKnownKeys = keys;\n }\n });\n\n\n // let $el = $(el);\n // $el.on(\"change\", \"input[type=\"checkbox\"]\", function() {\n // let checked = $el.find(\"input[type=\"checkbox\"]:checked\");\n // if (checked.length === 0) {\n // ctHandle.clear();\n // } else {\n // let keys = {};\n // checked.each(function() {\n // data.map[this.value].forEach(function(key) {\n // keys[key] = true;\n // });\n // });\n // let keyArray = Object.keys(keys);\n // keyArray.sort();\n // ctHandle.set(keyArray);\n // }\n // });\n\n return {\n suspend: function() {\n ctHandle.clear();\n },\n resume: function() {\n if (lastKnownKeys)\n ctHandle.set(lastKnownKeys);\n }\n };\n }\n});\n\n\n// Convert a number to a string with leading zeros\nfunction padZeros(n, digits) {\n let str = n.toString();\n while (str.length < digits)\n str = \"0\" + str;\n return str;\n}\n\n// Given a Date object, return a string in yyyy-mm-dd format, using the\n// UTC date. This may be a day off from the date in the local time zone.\nfunction formatDateUTC(date) {\n if (date instanceof Date) {\n return date.getUTCFullYear() + \"-\" +\n padZeros(date.getUTCMonth()+1, 2) + \"-\" +\n padZeros(date.getUTCDate(), 2);\n\n } else {\n return null;\n }\n}\n", + "import Events from \"./events\";\nimport grp from \"./group\";\nimport * as util from \"./util\";\n\n/**\n * Use this class to read and write (and listen for changes to) the selection\n * for a Crosstalk group. This is intended to be used for linked brushing.\n *\n * If two (or more) `SelectionHandle` instances in the same webpage share the\n * same group name, they will share the same state. Setting the selection using\n * one `SelectionHandle` instance will result in the `value` property instantly\n * changing across the others, and `\"change\"` event listeners on all instances\n * (including the one that initiated the sending) will fire.\n *\n * @param {string} [group] - The name of the Crosstalk group, or if none,\n * null or undefined (or any other falsy value). This can be changed later\n * via the [SelectionHandle#setGroup](#setGroup) method.\n * @param {Object} [extraInfo] - An object whose properties will be copied to\n * the event object whenever an event is emitted.\n */\nexport class SelectionHandle {\n\n constructor(group = null, extraInfo = null) {\n this._eventRelay = new Events();\n this._emitter = new util.SubscriptionTracker(this._eventRelay);\n\n // Name of the group we're currently tracking, if any. Can change over time.\n this._group = null;\n // The Var we're currently tracking, if any. Can change over time.\n this._var = null;\n // The event handler subscription we currently have on var.on(\"change\").\n this._varOnChangeSub = null;\n\n this._extraInfo = util.extend({ sender: this }, extraInfo);\n\n this.setGroup(group);\n }\n\n /**\n * Changes the Crosstalk group membership of this SelectionHandle. The group\n * being switched away from (if any) will not have its selection value\n * modified as a result of calling `setGroup`, even if this handle was the\n * most recent handle to set the selection of the group.\n *\n * The group being switched to (if any) will also not have its selection value\n * modified as a result of calling `setGroup`. If you want to set the\n * selection value of the new group, call `set` explicitly.\n *\n * @param {string} group - The name of the Crosstalk group, or null (or\n * undefined) to clear the group.\n */\n setGroup(group) {\n // If group is unchanged, do nothing\n if (this._group === group)\n return;\n // Treat null, undefined, and other falsy values the same\n if (!this._group && !group)\n return;\n\n if (this._var) {\n this._var.off(\"change\", this._varOnChangeSub);\n this._var = null;\n this._varOnChangeSub = null;\n }\n\n this._group = group;\n\n if (group) {\n this._var = grp(group).var(\"selection\");\n let sub = this._var.on(\"change\", (e) => {\n this._eventRelay.trigger(\"change\", e, this);\n });\n this._varOnChangeSub = sub;\n }\n }\n\n /**\n * Retrieves the current selection for the group represented by this\n * `SelectionHandle`.\n *\n * - If no selection is active, then this value will be falsy.\n * - If a selection is active, but no data points are selected, then this\n * value will be an empty array.\n * - If a selection is active, and data points are selected, then the keys\n * of the selected data points will be present in the array.\n */\n get value() {\n return this._var ? this._var.get() : null;\n }\n\n /**\n * Combines the given `extraInfo` (if any) with the handle's default\n * `_extraInfo` (if any).\n * @private\n */\n _mergeExtraInfo(extraInfo) {\n // Important incidental effect: shallow clone is returned\n return util.extend({},\n this._extraInfo ? this._extraInfo : null,\n extraInfo ? extraInfo : null);\n }\n\n /**\n * Overwrites the current selection for the group, and raises the `\"change\"`\n * event among all of the group's '`SelectionHandle` instances (including\n * this one).\n *\n * @fires SelectionHandle#change\n * @param {string[]} selectedKeys - Falsy, empty array, or array of keys (see\n * {@link SelectionHandle#value}).\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any options that were\n * passed into the `SelectionHandle` constructor).\n */\n set(selectedKeys, extraInfo) {\n if (this._var)\n this._var.set(selectedKeys, this._mergeExtraInfo(extraInfo));\n }\n\n /**\n * Overwrites the current selection for the group, and raises the `\"change\"`\n * event among all of the group's '`SelectionHandle` instances (including\n * this one).\n *\n * @fires SelectionHandle#change\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any that were passed\n * into the `SelectionHandle` constructor).\n */\n clear(extraInfo) {\n if (this._var)\n this.set(void 0, this._mergeExtraInfo(extraInfo));\n }\n\n /**\n * Subscribes to events on this `SelectionHandle`.\n *\n * @param {string} eventType - Indicates the type of events to listen to.\n * Currently, only `\"change\"` is supported.\n * @param {SelectionHandle~listener} listener - The callback function that\n * will be invoked when the event occurs.\n * @return {string} - A token to pass to {@link SelectionHandle#off} to cancel\n * this subscription.\n */\n on(eventType, listener) {\n return this._emitter.on(eventType, listener);\n }\n\n /**\n * Cancels event subscriptions created by {@link SelectionHandle#on}.\n *\n * @param {string} eventType - The type of event to unsubscribe.\n * @param {string|SelectionHandle~listener} listener - Either the callback\n * function previously passed into {@link SelectionHandle#on}, or the\n * string that was returned from {@link SelectionHandle#on}.\n */\n off(eventType, listener) {\n return this._emitter.off(eventType, listener);\n }\n\n /**\n * Shuts down the `SelectionHandle` object.\n *\n * Removes all event listeners that were added through this handle.\n */\n close() {\n this._emitter.removeAllListeners();\n this.setGroup(null);\n }\n}\n\n/**\n * @callback SelectionHandle~listener\n * @param {Object} event - An object containing details of the event. For\n * `\"change\"` events, this includes the properties `value` (the new\n * value of the selection, or `undefined` if no selection is active),\n * `oldValue` (the previous value of the selection), and `sender` (the\n * `SelectionHandle` instance that made the change).\n */\n\n/**\n * @event SelectionHandle#change\n * @type {object}\n * @property {object} value - The new value of the selection, or `undefined`\n * if no selection is active.\n * @property {object} oldValue - The previous value of the selection.\n * @property {SelectionHandle} sender - The `SelectionHandle` instance that\n * changed the value.\n */\n", + "export function extend(target, ...sources) {\n for (let i = 0; i < sources.length; i++) {\n let src = sources[i];\n if (typeof(src) === \"undefined\" || src === null)\n continue;\n\n for (let key in src) {\n if (src.hasOwnProperty(key)) {\n target[key] = src[key];\n }\n }\n }\n return target;\n}\n\nexport function checkSorted(list) {\n for (let i = 1; i < list.length; i++) {\n if (list[i] <= list[i-1]) {\n throw new Error(\"List is not sorted or contains duplicate\");\n }\n }\n}\n\nexport function diffSortedLists(a, b) {\n let i_a = 0;\n let i_b = 0;\n\n if (!a) a = [];\n if (!b) b = [];\n\n let a_only = [];\n let b_only = [];\n\n checkSorted(a);\n checkSorted(b);\n\n while (i_a < a.length && i_b < b.length) {\n if (a[i_a] === b[i_b]) {\n i_a++;\n i_b++;\n } else if (a[i_a] < b[i_b]) {\n a_only.push(a[i_a++]);\n } else {\n b_only.push(b[i_b++]);\n }\n }\n\n if (i_a < a.length)\n a_only = a_only.concat(a.slice(i_a));\n if (i_b < b.length)\n b_only = b_only.concat(b.slice(i_b));\n return {\n removed: a_only,\n added: b_only\n };\n}\n\n// Convert from wide: { colA: [1,2,3], colB: [4,5,6], ... }\n// to long: [ {colA: 1, colB: 4}, {colA: 2, colB: 5}, ... ]\nexport function dataframeToD3(df) {\n let names = [];\n let length;\n for (let name in df) {\n if (df.hasOwnProperty(name))\n names.push(name);\n if (typeof(df[name]) !== \"object\" || typeof(df[name].length) === \"undefined\") {\n throw new Error(\"All fields must be arrays\");\n } else if (typeof(length) !== \"undefined\" && length !== df[name].length) {\n throw new Error(\"All fields must be arrays of the same length\");\n }\n length = df[name].length;\n }\n let results = [];\n let item;\n for (let row = 0; row < length; row++) {\n item = {};\n for (let col = 0; col < names.length; col++) {\n item[names[col]] = df[names[col]][row];\n }\n results.push(item);\n }\n return results;\n}\n\n/**\n * Keeps track of all event listener additions/removals and lets all active\n * listeners be removed with a single operation.\n *\n * @private\n */\nexport class SubscriptionTracker {\n constructor(emitter) {\n this._emitter = emitter;\n this._subs = {};\n }\n\n on(eventType, listener) {\n let sub = this._emitter.on(eventType, listener);\n this._subs[sub] = eventType;\n return sub;\n }\n\n off(eventType, listener) {\n let sub = this._emitter.off(eventType, listener);\n if (sub) {\n delete this._subs[sub];\n }\n return sub;\n }\n\n removeAllListeners() {\n let current_subs = this._subs;\n this._subs = {};\n Object.keys(current_subs).forEach((sub) => {\n this._emitter.off(current_subs[sub], sub);\n });\n }\n}\n", + "import Events from \"./events\";\n\nexport default class Var {\n constructor(group, name, /*optional*/ value) {\n this._group = group;\n this._name = name;\n this._value = value;\n this._events = new Events();\n }\n\n get() {\n return this._value;\n }\n\n set(value, /*optional*/ event) {\n if (this._value === value) {\n // Do nothing; the value hasn't changed\n return;\n }\n let oldValue = this._value;\n this._value = value;\n // Alert JavaScript listeners that the value has changed\n let evt = {};\n if (event && typeof(event) === \"object\") {\n for (let k in event) {\n if (event.hasOwnProperty(k))\n evt[k] = event[k];\n }\n }\n evt.oldValue = oldValue;\n evt.value = value;\n this._events.trigger(\"change\", evt, this);\n\n // TODO: Make this extensible, to let arbitrary back-ends know that\n // something has changed\n if (global.Shiny && global.Shiny.onInputChange) {\n global.Shiny.onInputChange(\n \".clientValue-\" +\n (this._group.name !== null ? this._group.name + \"-\" : \"\") +\n this._name,\n typeof(value) === \"undefined\" ? null : value\n );\n }\n }\n\n on(eventType, listener) {\n return this._events.on(eventType, listener);\n }\n\n off(eventType, listener) {\n return this._events.off(eventType, listener);\n }\n}\n" + ] +} \ No newline at end of file diff --git a/public/site_libs/crosstalk-1.2.0/js/crosstalk.min.js b/public/site_libs/crosstalk-1.2.0/js/crosstalk.min.js new file mode 100644 index 00000000..b7ec0ac9 --- /dev/null +++ b/public/site_libs/crosstalk-1.2.0/js/crosstalk.min.js @@ -0,0 +1,2 @@ +!function o(u,a,l){function s(n,e){if(!a[n]){if(!u[n]){var t="function"==typeof require&&require;if(!e&&t)return t(n,!0);if(f)return f(n,!0);var r=new Error("Cannot find module '"+n+"'");throw r.code="MODULE_NOT_FOUND",r}var i=a[n]={exports:{}};u[n][0].call(i.exports,function(e){var t=u[n][1][e];return s(t||e)},i,i.exports,o,u,a,l)}return a[n].exports}for(var f="function"==typeof require&&require,e=0;e?@[\\\]^`{|}~])/g,"\\$1")+"']"),r=JSON.parse(n[0].innerText),i=e.factory(t,r);o(t).data("crosstalk-instance",i),o(t).addClass("crosstalk-input-bound")}if(t.Shiny){var e=new t.Shiny.InputBinding,u=t.jQuery;u.extend(e,{find:function(e){return u(e).find(".crosstalk-input")},initialize:function(e){var t,n;u(e).hasClass("crosstalk-input-bound")||(n=o(t=e),Object.keys(r).forEach(function(e){n.hasClass(e)&&!n.hasClass("crosstalk-input-bound")&&i(r[e],t)}))},getId:function(e){return e.id},getValue:function(e){},setValue:function(e,t){},receiveMessage:function(e,t){},subscribe:function(e,t){u(e).data("crosstalk-instance").resume()},unsubscribe:function(e){u(e).data("crosstalk-instance").suspend()}}),t.Shiny.inputBindings.register(e,"crosstalk.inputBinding")}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],7:[function(r,e,t){(function(e){"use strict";var t=function(e){{if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t}}(r("./input")),n=r("./filter");var a=e.jQuery;t.register({className:"crosstalk-input-checkboxgroup",factory:function(e,r){var i=new n.FilterHandle(r.group),o=void 0,u=a(e);return u.on("change","input[type='checkbox']",function(){var e=u.find("input[type='checkbox']:checked");if(0===e.length)o=null,i.clear();else{var t={};e.each(function(){r.map[this.value].forEach(function(e){t[e]=!0})});var n=Object.keys(t);n.sort(),o=n,i.set(n)}}),{suspend:function(){i.clear()},resume:function(){o&&i.set(o)}}}})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./filter":2,"./input":6}],8:[function(r,e,t){(function(e){"use strict";var t=n(r("./input")),l=n(r("./util")),s=r("./filter");function n(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t}var f=e.jQuery;t.register({className:"crosstalk-input-select",factory:function(e,n){var t=l.dataframeToD3(n.items),r={options:[{value:"",label:"(All)"}].concat(t),valueField:"value",labelField:"label",searchField:"label"},i=f(e).find("select")[0],o=f(i).selectize(r)[0].selectize,u=new s.FilterHandle(n.group),a=void 0;return o.on("change",function(){if(0===o.items.length)a=null,u.clear();else{var t={};o.items.forEach(function(e){n.map[e].forEach(function(e){t[e]=!0})});var e=Object.keys(t);e.sort(),a=e,u.set(e)}}),{suspend:function(){u.clear()},resume:function(){a&&u.set(a)}}}})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./filter":2,"./input":6,"./util":11}],9:[function(n,e,t){(function(e){"use strict";var d=function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var n=[],r=!0,i=!1,o=void 0;try{for(var u,a=e[Symbol.iterator]();!(r=(u=a.next()).done)&&(n.push(u.value),!t||n.length!==t);r=!0);}catch(e){i=!0,o=e}finally{try{!r&&a.return&&a.return()}finally{if(i)throw o}}return n}(e,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")},t=function(e){{if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t}}(n("./input")),a=n("./filter");var v=e.jQuery,p=e.strftime;function y(e,t){for(var n=e.toString();n.length {\n this._eventRelay.trigger(\"change\", e, this);\n });\n this._varOnChangeSub = sub;\n }\n }\n\n /**\n * Combine the given `extraInfo` (if any) with the handle's default\n * `_extraInfo` (if any).\n * @private\n */\n _mergeExtraInfo(extraInfo) {\n return util.extend({},\n this._extraInfo ? this._extraInfo : null,\n extraInfo ? extraInfo : null);\n }\n\n /**\n * Close the handle. This clears this handle's contribution to the filter set,\n * and unsubscribes all event listeners.\n */\n close() {\n this._emitter.removeAllListeners();\n this.clear();\n this.setGroup(null);\n }\n\n /**\n * Clear this handle's contribution to the filter set.\n *\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any options that were\n * passed into the `FilterHandle` constructor).\n * \n * @fires FilterHandle#change\n */\n clear(extraInfo) {\n if (!this._filterSet)\n return;\n this._filterSet.clear(this._id);\n this._onChange(extraInfo);\n }\n\n /**\n * Set this handle's contribution to the filter set. This array should consist\n * of the keys of the rows that _should_ be displayed; any keys that are not\n * present in the array will be considered _filtered out_. Note that multiple\n * `FilterHandle` instances in the group may each contribute an array of keys,\n * and only those keys that appear in _all_ of the arrays make it through the\n * filter.\n *\n * @param {string[]} keys - Empty array, or array of keys. To clear the\n * filter, don't pass an empty array; instead, use the\n * {@link FilterHandle#clear} method.\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any options that were\n * passed into the `FilterHandle` constructor).\n * \n * @fires FilterHandle#change\n */\n set(keys, extraInfo) {\n if (!this._filterSet)\n return;\n this._filterSet.update(this._id, keys);\n this._onChange(extraInfo);\n }\n\n /**\n * @return {string[]|null} - Either: 1) an array of keys that made it through\n * all of the `FilterHandle` instances, or, 2) `null`, which means no filter\n * is being applied (all data should be displayed).\n */\n get filteredKeys() {\n return this._filterSet ? this._filterSet.value : null;\n }\n\n /**\n * Subscribe to events on this `FilterHandle`.\n *\n * @param {string} eventType - Indicates the type of events to listen to.\n * Currently, only `\"change\"` is supported.\n * @param {FilterHandle~listener} listener - The callback function that\n * will be invoked when the event occurs.\n * @return {string} - A token to pass to {@link FilterHandle#off} to cancel\n * this subscription.\n */\n on(eventType, listener) {\n return this._emitter.on(eventType, listener);\n }\n\n /**\n * Cancel event subscriptions created by {@link FilterHandle#on}.\n *\n * @param {string} eventType - The type of event to unsubscribe.\n * @param {string|FilterHandle~listener} listener - Either the callback\n * function previously passed into {@link FilterHandle#on}, or the\n * string that was returned from {@link FilterHandle#on}.\n */\n off(eventType, listener) {\n return this._emitter.off(eventType, listener);\n }\n\n _onChange(extraInfo) {\n if (!this._filterSet)\n return;\n this._filterVar.set(this._filterSet.value, this._mergeExtraInfo(extraInfo));\n }\n\n /**\n * @callback FilterHandle~listener\n * @param {Object} event - An object containing details of the event. For\n * `\"change\"` events, this includes the properties `value` (the new\n * value of the filter set, or `null` if no filter set is active),\n * `oldValue` (the previous value of the filter set), and `sender` (the\n * `FilterHandle` instance that made the change).\n */\n\n}\n\n/**\n * @event FilterHandle#change\n * @type {object}\n * @property {object} value - The new value of the filter set, or `null`\n * if no filter set is active.\n * @property {object} oldValue - The previous value of the filter set.\n * @property {FilterHandle} sender - The `FilterHandle` instance that\n * changed the value.\n */\n","import { diffSortedLists } from \"./util\";\n\nfunction naturalComparator(a, b) {\n if (a === b) {\n return 0;\n } else if (a < b) {\n return -1;\n } else if (a > b) {\n return 1;\n }\n}\n\n/**\n * @private\n */\nexport default class FilterSet {\n constructor() {\n this.reset();\n }\n\n reset() {\n // Key: handle ID, Value: array of selected keys, or null\n this._handles = {};\n // Key: key string, Value: count of handles that include it\n this._keys = {};\n this._value = null;\n this._activeHandles = 0;\n }\n\n get value() {\n return this._value;\n }\n\n update(handleId, keys) {\n if (keys !== null) {\n keys = keys.slice(0); // clone before sorting\n keys.sort(naturalComparator);\n }\n\n let {added, removed} = diffSortedLists(this._handles[handleId], keys);\n this._handles[handleId] = keys;\n\n for (let i = 0; i < added.length; i++) {\n this._keys[added[i]] = (this._keys[added[i]] || 0) + 1;\n }\n for (let i = 0; i < removed.length; i++) {\n this._keys[removed[i]]--;\n }\n\n this._updateValue(keys);\n }\n\n /**\n * @param {string[]} keys Sorted array of strings that indicate\n * a superset of possible keys.\n * @private\n */\n _updateValue(keys = this._allKeys) {\n let handleCount = Object.keys(this._handles).length;\n if (handleCount === 0) {\n this._value = null;\n } else {\n this._value = [];\n for (let i = 0; i < keys.length; i++) {\n let count = this._keys[keys[i]];\n if (count === handleCount) {\n this._value.push(keys[i]);\n }\n }\n }\n }\n\n clear(handleId) {\n if (typeof(this._handles[handleId]) === \"undefined\") {\n return;\n }\n\n let keys = this._handles[handleId];\n if (!keys) {\n keys = [];\n }\n\n for (let i = 0; i < keys.length; i++) {\n this._keys[keys[i]]--;\n }\n delete this._handles[handleId];\n\n this._updateValue();\n }\n\n get _allKeys() {\n let allKeys = Object.keys(this._keys);\n allKeys.sort(naturalComparator);\n return allKeys;\n }\n}\n","import Var from \"./var\";\n\n// Use a global so that multiple copies of crosstalk.js can be loaded and still\n// have groups behave as singletons across all copies.\nglobal.__crosstalk_groups = global.__crosstalk_groups || {};\nlet groups = global.__crosstalk_groups;\n\nexport default function group(groupName) {\n if (groupName && typeof(groupName) === \"string\") {\n if (!groups.hasOwnProperty(groupName)) {\n groups[groupName] = new Group(groupName);\n }\n return groups[groupName];\n } else if (typeof(groupName) === \"object\" && groupName._vars && groupName.var) {\n // Appears to already be a group object\n return groupName;\n } else if (Array.isArray(groupName) &&\n groupName.length == 1 &&\n typeof(groupName[0]) === \"string\") {\n return group(groupName[0]);\n } else {\n throw new Error(\"Invalid groupName argument\");\n }\n}\n\nclass Group {\n constructor(name) {\n this.name = name;\n this._vars = {};\n }\n\n var(name) {\n if (!name || typeof(name) !== \"string\") {\n throw new Error(\"Invalid var name\");\n }\n\n if (!this._vars.hasOwnProperty(name))\n this._vars[name] = new Var(this, name);\n return this._vars[name];\n }\n\n has(name) {\n if (!name || typeof(name) !== \"string\") {\n throw new Error(\"Invalid var name\");\n }\n\n return this._vars.hasOwnProperty(name);\n }\n}\n","import group from \"./group\";\nimport { SelectionHandle } from \"./selection\";\nimport { FilterHandle } from \"./filter\";\nimport { bind } from \"./input\";\nimport \"./input_selectize\";\nimport \"./input_checkboxgroup\";\nimport \"./input_slider\";\n\nconst defaultGroup = group(\"default\");\n\nfunction var_(name) {\n return defaultGroup.var(name);\n}\n\nfunction has(name) {\n return defaultGroup.has(name);\n}\n\nif (global.Shiny) {\n global.Shiny.addCustomMessageHandler(\"update-client-value\", function(message) {\n if (typeof(message.group) === \"string\") {\n group(message.group).var(message.name).set(message.value);\n } else {\n var_(message.name).set(message.value);\n }\n });\n}\n\nconst crosstalk = {\n group: group,\n var: var_,\n has: has,\n SelectionHandle: SelectionHandle,\n FilterHandle: FilterHandle,\n bind: bind\n};\n\n/**\n * @namespace crosstalk\n */\nexport default crosstalk;\nglobal.crosstalk = crosstalk;\n","let $ = global.jQuery;\n\nlet bindings = {};\n\nexport function register(reg) {\n bindings[reg.className] = reg;\n if (global.document && global.document.readyState !== \"complete\") {\n $(() => {\n bind();\n });\n } else if (global.document) {\n setTimeout(bind, 100);\n }\n}\n\nexport function bind() {\n Object.keys(bindings).forEach(function(className) {\n let binding = bindings[className];\n $(\".\" + binding.className).not(\".crosstalk-input-bound\").each(function(i, el) {\n bindInstance(binding, el);\n });\n });\n}\n\n// Escape jQuery identifier\nfunction $escape(val) {\n return val.replace(/([!\"#$%&'()*+,./:;<=>?@[\\\\\\]^`{|}~])/g, \"\\\\$1\");\n}\n\nfunction bindEl(el) {\n let $el = $(el);\n Object.keys(bindings).forEach(function(className) {\n if ($el.hasClass(className) && !$el.hasClass(\"crosstalk-input-bound\")) {\n let binding = bindings[className];\n bindInstance(binding, el);\n }\n });\n}\n\nfunction bindInstance(binding, el) {\n let jsonEl = $(el).find(\"script[type='application/json'][data-for='\" + $escape(el.id) + \"']\");\n let data = JSON.parse(jsonEl[0].innerText);\n\n let instance = binding.factory(el, data);\n $(el).data(\"crosstalk-instance\", instance);\n $(el).addClass(\"crosstalk-input-bound\");\n}\n\nif (global.Shiny) {\n let inputBinding = new global.Shiny.InputBinding();\n let $ = global.jQuery;\n $.extend(inputBinding, {\n find: function(scope) {\n return $(scope).find(\".crosstalk-input\");\n },\n initialize: function(el) {\n if (!$(el).hasClass(\"crosstalk-input-bound\")) {\n bindEl(el);\n }\n },\n getId: function(el) {\n return el.id;\n },\n getValue: function(el) {\n\n },\n setValue: function(el, value) {\n\n },\n receiveMessage: function(el, data) {\n\n },\n subscribe: function(el, callback) {\n $(el).data(\"crosstalk-instance\").resume();\n },\n unsubscribe: function(el) {\n $(el).data(\"crosstalk-instance\").suspend();\n }\n });\n global.Shiny.inputBindings.register(inputBinding, \"crosstalk.inputBinding\");\n}\n","import * as input from \"./input\";\nimport { FilterHandle } from \"./filter\";\n\nlet $ = global.jQuery;\n\ninput.register({\n className: \"crosstalk-input-checkboxgroup\",\n\n factory: function(el, data) {\n /*\n * map: {\"groupA\": [\"keyA\", \"keyB\", ...], ...}\n * group: \"ct-groupname\"\n */\n let ctHandle = new FilterHandle(data.group);\n\n let lastKnownKeys;\n let $el = $(el);\n $el.on(\"change\", \"input[type='checkbox']\", function() {\n let checked = $el.find(\"input[type='checkbox']:checked\");\n if (checked.length === 0) {\n lastKnownKeys = null;\n ctHandle.clear();\n } else {\n let keys = {};\n checked.each(function() {\n data.map[this.value].forEach(function(key) {\n keys[key] = true;\n });\n });\n let keyArray = Object.keys(keys);\n keyArray.sort();\n lastKnownKeys = keyArray;\n ctHandle.set(keyArray);\n }\n });\n\n return {\n suspend: function() {\n ctHandle.clear();\n },\n resume: function() {\n if (lastKnownKeys)\n ctHandle.set(lastKnownKeys);\n }\n };\n }\n});\n","import * as input from \"./input\";\nimport * as util from \"./util\";\nimport { FilterHandle } from \"./filter\";\n\nlet $ = global.jQuery;\n\ninput.register({\n className: \"crosstalk-input-select\",\n\n factory: function(el, data) {\n /*\n * items: {value: [...], label: [...]}\n * map: {\"groupA\": [\"keyA\", \"keyB\", ...], ...}\n * group: \"ct-groupname\"\n */\n\n let first = [{value: \"\", label: \"(All)\"}];\n let items = util.dataframeToD3(data.items);\n let opts = {\n options: first.concat(items),\n valueField: \"value\",\n labelField: \"label\",\n searchField: \"label\"\n };\n\n let select = $(el).find(\"select\")[0];\n\n let selectize = $(select).selectize(opts)[0].selectize;\n\n let ctHandle = new FilterHandle(data.group);\n\n let lastKnownKeys;\n selectize.on(\"change\", function() {\n if (selectize.items.length === 0) {\n lastKnownKeys = null;\n ctHandle.clear();\n } else {\n let keys = {};\n selectize.items.forEach(function(group) {\n data.map[group].forEach(function(key) {\n keys[key] = true;\n });\n });\n let keyArray = Object.keys(keys);\n keyArray.sort();\n lastKnownKeys = keyArray;\n ctHandle.set(keyArray);\n }\n });\n\n return {\n suspend: function() {\n ctHandle.clear();\n },\n resume: function() {\n if (lastKnownKeys)\n ctHandle.set(lastKnownKeys);\n }\n };\n }\n});\n","import * as input from \"./input\";\nimport { FilterHandle } from \"./filter\";\n\nlet $ = global.jQuery;\nlet strftime = global.strftime;\n\ninput.register({\n className: \"crosstalk-input-slider\",\n\n factory: function(el, data) {\n /*\n * map: {\"groupA\": [\"keyA\", \"keyB\", ...], ...}\n * group: \"ct-groupname\"\n */\n let ctHandle = new FilterHandle(data.group);\n\n let opts = {};\n let $el = $(el).find(\"input\");\n let dataType = $el.data(\"data-type\");\n let timeFormat = $el.data(\"time-format\");\n let round = $el.data(\"round\");\n let timeFormatter;\n\n // Set up formatting functions\n if (dataType === \"date\") {\n timeFormatter = strftime.utc();\n opts.prettify = function(num) {\n return timeFormatter(timeFormat, new Date(num));\n };\n\n } else if (dataType === \"datetime\") {\n let timezone = $el.data(\"timezone\");\n if (timezone)\n timeFormatter = strftime.timezone(timezone);\n else\n timeFormatter = strftime;\n\n opts.prettify = function(num) {\n return timeFormatter(timeFormat, new Date(num));\n };\n } else if (dataType === \"number\") {\n if (typeof round !== \"undefined\")\n opts.prettify = function(num) {\n let factor = Math.pow(10, round);\n return Math.round(num * factor) / factor;\n };\n }\n\n $el.ionRangeSlider(opts);\n\n function getValue() {\n let result = $el.data(\"ionRangeSlider\").result;\n\n // Function for converting numeric value from slider to appropriate type.\n let convert;\n let dataType = $el.data(\"data-type\");\n if (dataType === \"date\") {\n convert = function(val) {\n return formatDateUTC(new Date(+val));\n };\n } else if (dataType === \"datetime\") {\n convert = function(val) {\n // Convert ms to s\n return +val / 1000;\n };\n } else {\n convert = function(val) { return +val; };\n }\n\n if ($el.data(\"ionRangeSlider\").options.type === \"double\") {\n return [convert(result.from), convert(result.to)];\n } else {\n return convert(result.from);\n }\n }\n\n let lastKnownKeys = null;\n\n $el.on(\"change.crosstalkSliderInput\", function(event) {\n if (!$el.data(\"updating\") && !$el.data(\"animating\")) {\n let [from, to] = getValue();\n let keys = [];\n for (let i = 0; i < data.values.length; i++) {\n let val = data.values[i];\n if (val >= from && val <= to) {\n keys.push(data.keys[i]);\n }\n }\n keys.sort();\n ctHandle.set(keys);\n lastKnownKeys = keys;\n }\n });\n\n\n // let $el = $(el);\n // $el.on(\"change\", \"input[type=\"checkbox\"]\", function() {\n // let checked = $el.find(\"input[type=\"checkbox\"]:checked\");\n // if (checked.length === 0) {\n // ctHandle.clear();\n // } else {\n // let keys = {};\n // checked.each(function() {\n // data.map[this.value].forEach(function(key) {\n // keys[key] = true;\n // });\n // });\n // let keyArray = Object.keys(keys);\n // keyArray.sort();\n // ctHandle.set(keyArray);\n // }\n // });\n\n return {\n suspend: function() {\n ctHandle.clear();\n },\n resume: function() {\n if (lastKnownKeys)\n ctHandle.set(lastKnownKeys);\n }\n };\n }\n});\n\n\n// Convert a number to a string with leading zeros\nfunction padZeros(n, digits) {\n let str = n.toString();\n while (str.length < digits)\n str = \"0\" + str;\n return str;\n}\n\n// Given a Date object, return a string in yyyy-mm-dd format, using the\n// UTC date. This may be a day off from the date in the local time zone.\nfunction formatDateUTC(date) {\n if (date instanceof Date) {\n return date.getUTCFullYear() + \"-\" +\n padZeros(date.getUTCMonth()+1, 2) + \"-\" +\n padZeros(date.getUTCDate(), 2);\n\n } else {\n return null;\n }\n}\n","import Events from \"./events\";\nimport grp from \"./group\";\nimport * as util from \"./util\";\n\n/**\n * Use this class to read and write (and listen for changes to) the selection\n * for a Crosstalk group. This is intended to be used for linked brushing.\n *\n * If two (or more) `SelectionHandle` instances in the same webpage share the\n * same group name, they will share the same state. Setting the selection using\n * one `SelectionHandle` instance will result in the `value` property instantly\n * changing across the others, and `\"change\"` event listeners on all instances\n * (including the one that initiated the sending) will fire.\n *\n * @param {string} [group] - The name of the Crosstalk group, or if none,\n * null or undefined (or any other falsy value). This can be changed later\n * via the [SelectionHandle#setGroup](#setGroup) method.\n * @param {Object} [extraInfo] - An object whose properties will be copied to\n * the event object whenever an event is emitted.\n */\nexport class SelectionHandle {\n\n constructor(group = null, extraInfo = null) {\n this._eventRelay = new Events();\n this._emitter = new util.SubscriptionTracker(this._eventRelay);\n\n // Name of the group we're currently tracking, if any. Can change over time.\n this._group = null;\n // The Var we're currently tracking, if any. Can change over time.\n this._var = null;\n // The event handler subscription we currently have on var.on(\"change\").\n this._varOnChangeSub = null;\n\n this._extraInfo = util.extend({ sender: this }, extraInfo);\n\n this.setGroup(group);\n }\n\n /**\n * Changes the Crosstalk group membership of this SelectionHandle. The group\n * being switched away from (if any) will not have its selection value\n * modified as a result of calling `setGroup`, even if this handle was the\n * most recent handle to set the selection of the group.\n *\n * The group being switched to (if any) will also not have its selection value\n * modified as a result of calling `setGroup`. If you want to set the\n * selection value of the new group, call `set` explicitly.\n *\n * @param {string} group - The name of the Crosstalk group, or null (or\n * undefined) to clear the group.\n */\n setGroup(group) {\n // If group is unchanged, do nothing\n if (this._group === group)\n return;\n // Treat null, undefined, and other falsy values the same\n if (!this._group && !group)\n return;\n\n if (this._var) {\n this._var.off(\"change\", this._varOnChangeSub);\n this._var = null;\n this._varOnChangeSub = null;\n }\n\n this._group = group;\n\n if (group) {\n this._var = grp(group).var(\"selection\");\n let sub = this._var.on(\"change\", (e) => {\n this._eventRelay.trigger(\"change\", e, this);\n });\n this._varOnChangeSub = sub;\n }\n }\n\n /**\n * Retrieves the current selection for the group represented by this\n * `SelectionHandle`.\n *\n * - If no selection is active, then this value will be falsy.\n * - If a selection is active, but no data points are selected, then this\n * value will be an empty array.\n * - If a selection is active, and data points are selected, then the keys\n * of the selected data points will be present in the array.\n */\n get value() {\n return this._var ? this._var.get() : null;\n }\n\n /**\n * Combines the given `extraInfo` (if any) with the handle's default\n * `_extraInfo` (if any).\n * @private\n */\n _mergeExtraInfo(extraInfo) {\n // Important incidental effect: shallow clone is returned\n return util.extend({},\n this._extraInfo ? this._extraInfo : null,\n extraInfo ? extraInfo : null);\n }\n\n /**\n * Overwrites the current selection for the group, and raises the `\"change\"`\n * event among all of the group's '`SelectionHandle` instances (including\n * this one).\n *\n * @fires SelectionHandle#change\n * @param {string[]} selectedKeys - Falsy, empty array, or array of keys (see\n * {@link SelectionHandle#value}).\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any options that were\n * passed into the `SelectionHandle` constructor).\n */\n set(selectedKeys, extraInfo) {\n if (this._var)\n this._var.set(selectedKeys, this._mergeExtraInfo(extraInfo));\n }\n\n /**\n * Overwrites the current selection for the group, and raises the `\"change\"`\n * event among all of the group's '`SelectionHandle` instances (including\n * this one).\n *\n * @fires SelectionHandle#change\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any that were passed\n * into the `SelectionHandle` constructor).\n */\n clear(extraInfo) {\n if (this._var)\n this.set(void 0, this._mergeExtraInfo(extraInfo));\n }\n\n /**\n * Subscribes to events on this `SelectionHandle`.\n *\n * @param {string} eventType - Indicates the type of events to listen to.\n * Currently, only `\"change\"` is supported.\n * @param {SelectionHandle~listener} listener - The callback function that\n * will be invoked when the event occurs.\n * @return {string} - A token to pass to {@link SelectionHandle#off} to cancel\n * this subscription.\n */\n on(eventType, listener) {\n return this._emitter.on(eventType, listener);\n }\n\n /**\n * Cancels event subscriptions created by {@link SelectionHandle#on}.\n *\n * @param {string} eventType - The type of event to unsubscribe.\n * @param {string|SelectionHandle~listener} listener - Either the callback\n * function previously passed into {@link SelectionHandle#on}, or the\n * string that was returned from {@link SelectionHandle#on}.\n */\n off(eventType, listener) {\n return this._emitter.off(eventType, listener);\n }\n\n /**\n * Shuts down the `SelectionHandle` object.\n *\n * Removes all event listeners that were added through this handle.\n */\n close() {\n this._emitter.removeAllListeners();\n this.setGroup(null);\n }\n}\n\n/**\n * @callback SelectionHandle~listener\n * @param {Object} event - An object containing details of the event. For\n * `\"change\"` events, this includes the properties `value` (the new\n * value of the selection, or `undefined` if no selection is active),\n * `oldValue` (the previous value of the selection), and `sender` (the\n * `SelectionHandle` instance that made the change).\n */\n\n/**\n * @event SelectionHandle#change\n * @type {object}\n * @property {object} value - The new value of the selection, or `undefined`\n * if no selection is active.\n * @property {object} oldValue - The previous value of the selection.\n * @property {SelectionHandle} sender - The `SelectionHandle` instance that\n * changed the value.\n */\n","export function extend(target, ...sources) {\n for (let i = 0; i < sources.length; i++) {\n let src = sources[i];\n if (typeof(src) === \"undefined\" || src === null)\n continue;\n\n for (let key in src) {\n if (src.hasOwnProperty(key)) {\n target[key] = src[key];\n }\n }\n }\n return target;\n}\n\nexport function checkSorted(list) {\n for (let i = 1; i < list.length; i++) {\n if (list[i] <= list[i-1]) {\n throw new Error(\"List is not sorted or contains duplicate\");\n }\n }\n}\n\nexport function diffSortedLists(a, b) {\n let i_a = 0;\n let i_b = 0;\n\n if (!a) a = [];\n if (!b) b = [];\n\n let a_only = [];\n let b_only = [];\n\n checkSorted(a);\n checkSorted(b);\n\n while (i_a < a.length && i_b < b.length) {\n if (a[i_a] === b[i_b]) {\n i_a++;\n i_b++;\n } else if (a[i_a] < b[i_b]) {\n a_only.push(a[i_a++]);\n } else {\n b_only.push(b[i_b++]);\n }\n }\n\n if (i_a < a.length)\n a_only = a_only.concat(a.slice(i_a));\n if (i_b < b.length)\n b_only = b_only.concat(b.slice(i_b));\n return {\n removed: a_only,\n added: b_only\n };\n}\n\n// Convert from wide: { colA: [1,2,3], colB: [4,5,6], ... }\n// to long: [ {colA: 1, colB: 4}, {colA: 2, colB: 5}, ... ]\nexport function dataframeToD3(df) {\n let names = [];\n let length;\n for (let name in df) {\n if (df.hasOwnProperty(name))\n names.push(name);\n if (typeof(df[name]) !== \"object\" || typeof(df[name].length) === \"undefined\") {\n throw new Error(\"All fields must be arrays\");\n } else if (typeof(length) !== \"undefined\" && length !== df[name].length) {\n throw new Error(\"All fields must be arrays of the same length\");\n }\n length = df[name].length;\n }\n let results = [];\n let item;\n for (let row = 0; row < length; row++) {\n item = {};\n for (let col = 0; col < names.length; col++) {\n item[names[col]] = df[names[col]][row];\n }\n results.push(item);\n }\n return results;\n}\n\n/**\n * Keeps track of all event listener additions/removals and lets all active\n * listeners be removed with a single operation.\n *\n * @private\n */\nexport class SubscriptionTracker {\n constructor(emitter) {\n this._emitter = emitter;\n this._subs = {};\n }\n\n on(eventType, listener) {\n let sub = this._emitter.on(eventType, listener);\n this._subs[sub] = eventType;\n return sub;\n }\n\n off(eventType, listener) {\n let sub = this._emitter.off(eventType, listener);\n if (sub) {\n delete this._subs[sub];\n }\n return sub;\n }\n\n removeAllListeners() {\n let current_subs = this._subs;\n this._subs = {};\n Object.keys(current_subs).forEach((sub) => {\n this._emitter.off(current_subs[sub], sub);\n });\n }\n}\n","import Events from \"./events\";\n\nexport default class Var {\n constructor(group, name, /*optional*/ value) {\n this._group = group;\n this._name = name;\n this._value = value;\n this._events = new Events();\n }\n\n get() {\n return this._value;\n }\n\n set(value, /*optional*/ event) {\n if (this._value === value) {\n // Do nothing; the value hasn't changed\n return;\n }\n let oldValue = this._value;\n this._value = value;\n // Alert JavaScript listeners that the value has changed\n let evt = {};\n if (event && typeof(event) === \"object\") {\n for (let k in event) {\n if (event.hasOwnProperty(k))\n evt[k] = event[k];\n }\n }\n evt.oldValue = oldValue;\n evt.value = value;\n this._events.trigger(\"change\", evt, this);\n\n // TODO: Make this extensible, to let arbitrary back-ends know that\n // something has changed\n if (global.Shiny && global.Shiny.onInputChange) {\n global.Shiny.onInputChange(\n \".clientValue-\" +\n (this._group.name !== null ? this._group.name + \"-\" : \"\") +\n this._name,\n typeof(value) === \"undefined\" ? null : value\n );\n }\n }\n\n on(eventType, listener) {\n return this._events.on(eventType, listener);\n }\n\n off(eventType, listener) {\n return this._events.off(eventType, listener);\n }\n}\n"]} \ No newline at end of file diff --git a/public/site_libs/crosstalk-1.2.0/scss/crosstalk.scss b/public/site_libs/crosstalk-1.2.0/scss/crosstalk.scss new file mode 100644 index 00000000..35665616 --- /dev/null +++ b/public/site_libs/crosstalk-1.2.0/scss/crosstalk.scss @@ -0,0 +1,75 @@ +/* Adjust margins outwards, so column contents line up with the edges of the + parent of container-fluid. */ +.container-fluid.crosstalk-bscols { + margin-left: -30px; + margin-right: -30px; + white-space: normal; +} + +/* But don't adjust the margins outwards if we're directly under the body, + i.e. we were the top-level of something at the console. */ +body > .container-fluid.crosstalk-bscols { + margin-left: auto; + margin-right: auto; +} + +.crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { + display: inline-block; + padding-right: 12px; + vertical-align: top; +} + +@media only screen and (max-width:480px) { + .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { + display: block; + padding-right: inherit; + } +} + +/* Relevant BS3 styles to make filter_checkbox() look reasonable without Bootstrap */ +.crosstalk-input { + margin-bottom: 15px; /* a la .form-group */ + .control-label { + margin-bottom: 0; + vertical-align: middle; + } + input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px; + line-height: normal; + } + .checkbox { + position: relative; + display: block; + margin-top: 10px; + margin-bottom: 10px; + } + .checkbox > label{ + padding-left: 20px; + margin-bottom: 0; + font-weight: 400; + cursor: pointer; + } + .checkbox input[type="checkbox"], + .checkbox-inline input[type="checkbox"] { + position: absolute; + margin-top: 2px; + margin-left: -20px; + } + .checkbox + .checkbox { + margin-top: -5px; + } + .checkbox-inline { + position: relative; + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + font-weight: 400; + vertical-align: middle; + cursor: pointer; + } + .checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; + } +} diff --git a/public/site_libs/datatables-binding-0.29/datatables.js b/public/site_libs/datatables-binding-0.29/datatables.js new file mode 100644 index 00000000..b930851b --- /dev/null +++ b/public/site_libs/datatables-binding-0.29/datatables.js @@ -0,0 +1,1515 @@ +(function() { + +// some helper functions: using a global object DTWidget so that it can be used +// in JS() code, e.g. datatable(options = list(foo = JS('code'))); unlike R's +// dynamic scoping, when 'code' is eval'ed, JavaScript does not know objects +// from the "parent frame", e.g. JS('DTWidget') will not work unless it was made +// a global object +var DTWidget = {}; + +// 123456666.7890 -> 123,456,666.7890 +var markInterval = function(d, digits, interval, mark, decMark, precision) { + x = precision ? d.toPrecision(digits) : d.toFixed(digits); + if (!/^-?[\d.]+$/.test(x)) return x; + var xv = x.split('.'); + if (xv.length > 2) return x; // should have at most one decimal point + xv[0] = xv[0].replace(new RegExp('\\B(?=(\\d{' + interval + '})+(?!\\d))', 'g'), mark); + return xv.join(decMark); +}; + +DTWidget.formatCurrency = function(data, currency, digits, interval, mark, decMark, before, zeroPrint) { + var d = parseFloat(data); + if (isNaN(d)) return ''; + if (zeroPrint !== null && d === 0.0) return zeroPrint; + var res = markInterval(d, digits, interval, mark, decMark); + res = before ? (/^-/.test(res) ? '-' + currency + res.replace(/^-/, '') : currency + res) : + res + currency; + return res; +}; + +DTWidget.formatString = function(data, prefix, suffix) { + var d = data; + if (d === null) return ''; + return prefix + d + suffix; +}; + +DTWidget.formatPercentage = function(data, digits, interval, mark, decMark, zeroPrint) { + var d = parseFloat(data); + if (isNaN(d)) return ''; + if (zeroPrint !== null && d === 0.0) return zeroPrint; + return markInterval(d * 100, digits, interval, mark, decMark) + '%'; +}; + +DTWidget.formatRound = function(data, digits, interval, mark, decMark, zeroPrint) { + var d = parseFloat(data); + if (isNaN(d)) return ''; + if (zeroPrint !== null && d === 0.0) return zeroPrint; + return markInterval(d, digits, interval, mark, decMark); +}; + +DTWidget.formatSignif = function(data, digits, interval, mark, decMark, zeroPrint) { + var d = parseFloat(data); + if (isNaN(d)) return ''; + if (zeroPrint !== null && d === 0.0) return zeroPrint; + return markInterval(d, digits, interval, mark, decMark, true); +}; + +DTWidget.formatDate = function(data, method, params) { + var d = data; + if (d === null) return ''; + // (new Date('2015-10-28')).toDateString() may return 2015-10-27 because the + // actual time created could be like 'Tue Oct 27 2015 19:00:00 GMT-0500 (CDT)', + // i.e. the date-only string is treated as UTC time instead of local time + if ((method === 'toDateString' || method === 'toLocaleDateString') && /^\d{4,}\D\d{2}\D\d{2}$/.test(d)) { + d = d.split(/\D/); + d = new Date(d[0], d[1] - 1, d[2]); + } else { + d = new Date(d); + } + return d[method].apply(d, params); +}; + +window.DTWidget = DTWidget; + +// A helper function to update the properties of existing filters +var setFilterProps = function(td, props) { + // Update enabled/disabled state + var $input = $(td).find('input').first(); + var searchable = $input.data('searchable'); + $input.prop('disabled', !searchable || props.disabled); + + // Based on the filter type, set its new values + var type = td.getAttribute('data-type'); + if (['factor', 'logical'].includes(type)) { + // Reformat the new dropdown options for use with selectize + var new_vals = props.params.options.map(function(item) { + return { text: item, value: item }; + }); + + // Find the selectize object + var dropdown = $(td).find('.selectized').eq(0)[0].selectize; + + // Note the current values + var old_vals = dropdown.getValue(); + + // Remove the existing values + dropdown.clearOptions(); + + // Add the new options + dropdown.addOption(new_vals); + + // Preserve the existing values + dropdown.setValue(old_vals); + + } else if (['number', 'integer', 'date', 'time'].includes(type)) { + // Apply internal scaling to new limits. Updating scale not yet implemented. + var slider = $(td).find('.noUi-target').eq(0); + var scale = Math.pow(10, Math.max(0, +slider.data('scale') || 0)); + var new_vals = [props.params.min * scale, props.params.max * scale]; + + // Note what the new limits will be just for this filter + var new_lims = new_vals.slice(); + + // Determine the current values and limits + var old_vals = slider.val().map(Number); + var old_lims = slider.noUiSlider('options').range; + old_lims = [old_lims.min, old_lims.max]; + + // Preserve the current values if filters have been applied; otherwise, apply no filtering + if (old_vals[0] != old_lims[0]) { + new_vals[0] = Math.max(old_vals[0], new_vals[0]); + } + + if (old_vals[1] != old_lims[1]) { + new_vals[1] = Math.min(old_vals[1], new_vals[1]); + } + + // Update the endpoints of the slider + slider.noUiSlider({ + start: new_vals, + range: {'min': new_lims[0], 'max': new_lims[1]} + }, true); + } +}; + +var transposeArray2D = function(a) { + return a.length === 0 ? a : HTMLWidgets.transposeArray2D(a); +}; + +var crosstalkPluginsInstalled = false; + +function maybeInstallCrosstalkPlugins() { + if (crosstalkPluginsInstalled) + return; + crosstalkPluginsInstalled = true; + + $.fn.dataTable.ext.afnFiltering.push( + function(oSettings, aData, iDataIndex) { + var ctfilter = oSettings.nTable.ctfilter; + if (ctfilter && !ctfilter[iDataIndex]) + return false; + + var ctselect = oSettings.nTable.ctselect; + if (ctselect && !ctselect[iDataIndex]) + return false; + + return true; + } + ); +} + +HTMLWidgets.widget({ + name: "datatables", + type: "output", + renderOnNullValue: true, + initialize: function(el, width, height) { + // in order that the type=number inputs return a number + $.valHooks.number = { + get: function(el) { + var value = parseFloat(el.value); + return isNaN(value) ? "" : value; + } + }; + $(el).html(' '); + return { + data: null, + ctfilterHandle: new crosstalk.FilterHandle(), + ctfilterSubscription: null, + ctselectHandle: new crosstalk.SelectionHandle(), + ctselectSubscription: null + }; + }, + renderValue: function(el, data, instance) { + if (el.offsetWidth === 0 || el.offsetHeight === 0) { + instance.data = data; + return; + } + instance.data = null; + var $el = $(el); + $el.empty(); + + if (data === null) { + $el.append(' '); + // clear previous Shiny inputs (if any) + for (var i in instance.clearInputs) instance.clearInputs[i](); + instance.clearInputs = {}; + return; + } + + var crosstalkOptions = data.crosstalkOptions; + if (!crosstalkOptions) crosstalkOptions = { + 'key': null, 'group': null + }; + if (crosstalkOptions.group) { + maybeInstallCrosstalkPlugins(); + instance.ctfilterHandle.setGroup(crosstalkOptions.group); + instance.ctselectHandle.setGroup(crosstalkOptions.group); + } + + // if we are in the viewer then we always want to fillContainer and + // and autoHideNavigation (unless the user has explicitly set these) + if (window.HTMLWidgets.viewerMode) { + if (!data.hasOwnProperty("fillContainer")) + data.fillContainer = true; + if (!data.hasOwnProperty("autoHideNavigation")) + data.autoHideNavigation = true; + } + + // propagate fillContainer to instance (so we have it in resize) + instance.fillContainer = data.fillContainer; + + var cells = data.data; + + if (cells instanceof Array) cells = transposeArray2D(cells); + + $el.append(data.container); + var $table = $el.find('table'); + if (data.class) $table.addClass(data.class); + if (data.caption) $table.prepend(data.caption); + + if (!data.selection) data.selection = { + mode: 'none', selected: null, target: 'row', selectable: null + }; + if (HTMLWidgets.shinyMode && data.selection.mode !== 'none' && + data.selection.target === 'row+column') { + if ($table.children('tfoot').length === 0) { + $table.append($('')); + $table.find('thead tr').clone().appendTo($table.find('tfoot')); + } + } + + // column filters + var filterRow; + switch (data.filter) { + case 'top': + $table.children('thead').append(data.filterHTML); + filterRow = $table.find('thead tr:last td'); + break; + case 'bottom': + if ($table.children('tfoot').length === 0) { + $table.append($('')); + } + $table.children('tfoot').prepend(data.filterHTML); + filterRow = $table.find('tfoot tr:first td'); + break; + } + + var options = { searchDelay: 1000 }; + if (cells !== null) $.extend(options, { + data: cells + }); + + // options for fillContainer + var bootstrapActive = typeof($.fn.popover) != 'undefined'; + if (instance.fillContainer) { + + // force scrollX/scrollY and turn off autoWidth + options.scrollX = true; + options.scrollY = "100px"; // can be any value, we'll adjust below + + // if we aren't paginating then move around the info/filter controls + // to save space at the bottom and rephrase the info callback + if (data.options.paging === false) { + + // we know how to do this cleanly for bootstrap, not so much + // for other themes/layouts + if (bootstrapActive) { + options.dom = "<'row'<'col-sm-4'i><'col-sm-8'f>>" + + "<'row'<'col-sm-12'tr>>"; + } + + options.fnInfoCallback = function(oSettings, iStart, iEnd, + iMax, iTotal, sPre) { + return Number(iTotal).toLocaleString() + " records"; + }; + } + } + + // auto hide navigation if requested + // Note, this only works on client-side processing mode as on server-side, + // cells (data.data) is null; In addition, we require the pageLength option + // being provided explicitly to enable this. Despite we may be able to deduce + // the default value of pageLength, it may complicate things so we'd rather + // put this responsiblity to users and warn them on the R side. + if (data.autoHideNavigation === true && data.options.paging !== false) { + // strip all nav if length >= cells + if ((cells instanceof Array) && data.options.pageLength >= cells.length) + options.dom = bootstrapActive ? "<'row'<'col-sm-12'tr>>" : "t"; + // alternatively lean things out for flexdashboard mobile portrait + else if (bootstrapActive && window.FlexDashboard && window.FlexDashboard.isMobilePhone()) + options.dom = "<'row'<'col-sm-12'f>>" + + "<'row'<'col-sm-12'tr>>" + + "<'row'<'col-sm-12'p>>"; + } + + $.extend(true, options, data.options || {}); + + var searchCols = options.searchCols; + if (searchCols) { + searchCols = searchCols.map(function(x) { + return x === null ? '' : x.search; + }); + // FIXME: this means I don't respect the escapeRegex setting + delete options.searchCols; + } + + // server-side processing? + var server = options.serverSide === true; + + // use the dataSrc function to pre-process JSON data returned from R + var DT_rows_all = [], DT_rows_current = []; + if (server && HTMLWidgets.shinyMode && typeof options.ajax === 'object' && + /^session\/[\da-z]+\/dataobj/.test(options.ajax.url) && !options.ajax.dataSrc) { + options.ajax.dataSrc = function(json) { + DT_rows_all = $.makeArray(json.DT_rows_all); + DT_rows_current = $.makeArray(json.DT_rows_current); + var data = json.data; + if (!colReorderEnabled()) return data; + var table = $table.DataTable(), order = table.colReorder.order(), flag = true, i, j, row; + for (i = 0; i < order.length; ++i) if (order[i] !== i) flag = false; + if (flag) return data; + for (i = 0; i < data.length; ++i) { + row = data[i].slice(); + for (j = 0; j < order.length; ++j) data[i][j] = row[order[j]]; + } + return data; + }; + } + + var thiz = this; + if (instance.fillContainer) $table.on('init.dt', function(e) { + thiz.fillAvailableHeight(el, $(el).innerHeight()); + }); + // If the page contains serveral datatables and one of which enables colReorder, + // the table.colReorder.order() function will exist but throws error when called. + // So it seems like the only way to know if colReorder is enabled or not is to + // check the options. + var colReorderEnabled = function() { return "colReorder" in options; }; + var table = $table.DataTable(options); + $el.data('datatable', table); + + // Unregister previous Crosstalk event subscriptions, if they exist + if (instance.ctfilterSubscription) { + instance.ctfilterHandle.off("change", instance.ctfilterSubscription); + instance.ctfilterSubscription = null; + } + if (instance.ctselectSubscription) { + instance.ctselectHandle.off("change", instance.ctselectSubscription); + instance.ctselectSubscription = null; + } + + if (!crosstalkOptions.group) { + $table[0].ctfilter = null; + $table[0].ctselect = null; + } else { + var key = crosstalkOptions.key; + function keysToMatches(keys) { + if (!keys) { + return null; + } else { + var selectedKeys = {}; + for (var i = 0; i < keys.length; i++) { + selectedKeys[keys[i]] = true; + } + var matches = {}; + for (var j = 0; j < key.length; j++) { + if (selectedKeys[key[j]]) + matches[j] = true; + } + return matches; + } + } + + function applyCrosstalkFilter(e) { + $table[0].ctfilter = keysToMatches(e.value); + table.draw(); + } + instance.ctfilterSubscription = instance.ctfilterHandle.on("change", applyCrosstalkFilter); + applyCrosstalkFilter({value: instance.ctfilterHandle.filteredKeys}); + + function applyCrosstalkSelection(e) { + if (e.sender !== instance.ctselectHandle) { + table + .rows('.' + selClass, {search: 'applied'}) + .nodes() + .to$() + .removeClass(selClass); + if (selectedRows) + changeInput('rows_selected', selectedRows(), void 0, true); + } + + if (e.sender !== instance.ctselectHandle && e.value && e.value.length) { + var matches = keysToMatches(e.value); + + // persistent selection with plotly (& leaflet) + var ctOpts = crosstalk.var("plotlyCrosstalkOpts").get() || {}; + if (ctOpts.persistent === true) { + var matches = $.extend(matches, $table[0].ctselect); + } + + $table[0].ctselect = matches; + table.draw(); + } else { + if ($table[0].ctselect) { + $table[0].ctselect = null; + table.draw(); + } + } + } + instance.ctselectSubscription = instance.ctselectHandle.on("change", applyCrosstalkSelection); + // TODO: This next line doesn't seem to work when renderDataTable is used + applyCrosstalkSelection({value: instance.ctselectHandle.value}); + } + + var inArray = function(val, array) { + return $.inArray(val, $.makeArray(array)) > -1; + }; + + // search the i-th column + var searchColumn = function(i, value) { + var regex = false, ci = true; + if (options.search) { + regex = options.search.regex, + ci = options.search.caseInsensitive !== false; + } + return table.column(i).search(value, regex, !regex, ci); + }; + + if (data.filter !== 'none') { + + filterRow.each(function(i, td) { + + var $td = $(td), type = $td.data('type'), filter; + var $input = $td.children('div').first().children('input'); + var disabled = $input.prop('disabled'); + var searchable = table.settings()[0].aoColumns[i].bSearchable; + $input.prop('disabled', !searchable || disabled); + $input.data('searchable', searchable); // for updating later + $input.on('input blur', function() { + $input.next('span').toggle(Boolean($input.val())); + }); + // Bootstrap sets pointer-events to none and we won't be able to click + // the clear button + $input.next('span').css('pointer-events', 'auto').hide().click(function() { + $(this).hide().prev('input').val('').trigger('input').focus(); + }); + var searchCol; // search string for this column + if (searchCols && searchCols[i]) { + searchCol = searchCols[i]; + $input.val(searchCol).trigger('input'); + } + var $x = $td.children('div').last(); + + // remove the overflow: hidden attribute of the scrollHead + // (otherwise the scrolling table body obscures the filters) + // The workaround and the discussion from + // https://github.com/rstudio/DT/issues/554#issuecomment-518007347 + // Otherwise the filter selection will not be anchored to the values + // when the columns number is many and scrollX is enabled. + var scrollHead = $(el).find('.dataTables_scrollHead,.dataTables_scrollFoot'); + var cssOverflowHead = scrollHead.css('overflow'); + var scrollBody = $(el).find('.dataTables_scrollBody'); + var cssOverflowBody = scrollBody.css('overflow'); + var scrollTable = $(el).find('.dataTables_scroll'); + var cssOverflowTable = scrollTable.css('overflow'); + if (cssOverflowHead === 'hidden') { + $x.on('show hide', function(e) { + if (e.type === 'show') { + scrollHead.css('overflow', 'visible'); + scrollBody.css('overflow', 'visible'); + scrollTable.css('overflow-x', 'scroll'); + } else { + scrollHead.css('overflow', cssOverflowHead); + scrollBody.css('overflow', cssOverflowBody); + scrollTable.css('overflow-x', cssOverflowTable); + } + }); + $x.css('z-index', 25); + } + + if (inArray(type, ['factor', 'logical'])) { + $input.on({ + click: function() { + $input.parent().hide(); $x.show().trigger('show'); filter[0].selectize.focus(); + }, + input: function() { + if ($input.val() === '') filter[0].selectize.setValue([]); + } + }); + var $input2 = $x.children('select'); + filter = $input2.selectize({ + options: $input2.data('options').map(function(v, i) { + return ({text: v, value: v}); + }), + plugins: ['remove_button'], + hideSelected: true, + onChange: function(value) { + if (value === null) value = []; // compatibility with jQuery 3.0 + $input.val(value.length ? JSON.stringify(value) : ''); + if (value.length) $input.trigger('input'); + $input.attr('title', $input.val()); + if (server) { + table.column(i).search(value.length ? JSON.stringify(value) : '').draw(); + return; + } + // turn off filter if nothing selected + $td.data('filter', value.length > 0); + table.draw(); // redraw table, and filters will be applied + } + }); + if (searchCol) filter[0].selectize.setValue(JSON.parse(searchCol)); + filter[0].selectize.on('blur', function() { + $x.hide().trigger('hide'); $input.parent().show(); $input.trigger('blur'); + }); + filter.next('div').css('margin-bottom', 'auto'); + } else if (type === 'character') { + var fun = function() { + searchColumn(i, $input.val()).draw(); + }; + if (server) { + fun = $.fn.dataTable.util.throttle(fun, options.searchDelay); + } + $input.on('input', fun); + } else if (inArray(type, ['number', 'integer', 'date', 'time'])) { + var $x0 = $x; + $x = $x0.children('div').first(); + $x0.css({ + 'background-color': '#fff', + 'border': '1px #ddd solid', + 'border-radius': '4px', + 'padding': data.vertical ? '35px 20px': '20px 20px 10px 20px' + }); + var $spans = $x0.children('span').css({ + 'margin-top': data.vertical ? '0' : '10px', + 'white-space': 'nowrap' + }); + var $span1 = $spans.first(), $span2 = $spans.last(); + var r1 = +$x.data('min'), r2 = +$x.data('max'); + // when the numbers are too small or have many decimal places, the + // slider may have numeric precision problems (#150) + var scale = Math.pow(10, Math.max(0, +$x.data('scale') || 0)); + r1 = Math.round(r1 * scale); r2 = Math.round(r2 * scale); + var scaleBack = function(x, scale) { + if (scale === 1) return x; + var d = Math.round(Math.log(scale) / Math.log(10)); + // to avoid problems like 3.423/100 -> 0.034230000000000003 + return (x / scale).toFixed(d); + }; + var slider_min = function() { + return filter.noUiSlider('options').range.min; + }; + var slider_max = function() { + return filter.noUiSlider('options').range.max; + }; + $input.on({ + focus: function() { + $x0.show().trigger('show'); + // first, make sure the slider div leaves at least 20px between + // the two (slider value) span's + $x0.width(Math.max(160, $span1.outerWidth() + $span2.outerWidth() + 20)); + // then, if the input is really wide or slider is vertical, + // make the slider the same width as the input + if ($x0.outerWidth() < $input.outerWidth() || data.vertical) { + $x0.outerWidth($input.outerWidth()); + } + // make sure the slider div does not reach beyond the right margin + if ($(window).width() < $x0.offset().left + $x0.width()) { + $x0.offset({ + 'left': $input.offset().left + $input.outerWidth() - $x0.outerWidth() + }); + } + }, + blur: function() { + $x0.hide().trigger('hide'); + }, + input: function() { + if ($input.val() === '') filter.val([slider_min(), slider_max()]); + }, + change: function() { + var v = $input.val().replace(/\s/g, ''); + if (v === '') return; + v = v.split('...'); + if (v.length !== 2) { + $input.parent().addClass('has-error'); + return; + } + if (v[0] === '') v[0] = slider_min(); + if (v[1] === '') v[1] = slider_max(); + $input.parent().removeClass('has-error'); + // treat date as UTC time at midnight + var strTime = function(x) { + var s = type === 'date' ? 'T00:00:00Z' : ''; + var t = new Date(x + s).getTime(); + // add 10 minutes to date since it does not hurt the date, and + // it helps avoid the tricky floating point arithmetic problems, + // e.g. sometimes the date may be a few milliseconds earlier + // than the midnight due to precision problems in noUiSlider + return type === 'date' ? t + 3600000 : t; + }; + if (inArray(type, ['date', 'time'])) { + v[0] = strTime(v[0]); + v[1] = strTime(v[1]); + } + if (v[0] != slider_min()) v[0] *= scale; + if (v[1] != slider_max()) v[1] *= scale; + filter.val(v); + } + }); + var formatDate = function(d, isoFmt) { + d = scaleBack(d, scale); + if (type === 'number') return d; + if (type === 'integer') return parseInt(d); + var x = new Date(+d); + var fmt = ('filterDateFmt' in data) ? data.filterDateFmt[i] : undefined; + if (fmt !== undefined && isoFmt === false) return x[fmt.method].apply(x, fmt.params); + if (type === 'date') { + var pad0 = function(x) { + return ('0' + x).substr(-2, 2); + }; + return x.getUTCFullYear() + '-' + pad0(1 + x.getUTCMonth()) + + '-' + pad0(x.getUTCDate()); + } else { + return x.toISOString(); + } + }; + var opts = type === 'date' ? { step: 60 * 60 * 1000 } : + type === 'integer' ? { step: 1 } : {}; + + opts.orientation = data.vertical ? 'vertical': 'horizontal'; + opts.direction = data.vertical ? 'rtl': 'ltr'; + + filter = $x.noUiSlider($.extend({ + start: [r1, r2], + range: {min: r1, max: r2}, + connect: true + }, opts)); + if (scale > 1) (function() { + var t1 = r1, t2 = r2; + var val = filter.val(); + while (val[0] > r1 || val[1] < r2) { + if (val[0] > r1) { + t1 -= val[0] - r1; + } + if (val[1] < r2) { + t2 += r2 - val[1]; + } + filter = $x.noUiSlider($.extend({ + start: [t1, t2], + range: {min: t1, max: t2}, + connect: true + }, opts), true); + val = filter.val(); + } + r1 = t1; r2 = t2; + })(); + var updateSliderText = function(v1, v2) { + $span1.text(formatDate(v1, false)); $span2.text(formatDate(v2, false)); + }; + updateSliderText(r1, r2); + var updateSlider = function(e) { + var val = filter.val(); + // turn off filter if in full range + $td.data('filter', val[0] > slider_min() || val[1] < slider_max()); + var v1 = formatDate(val[0]), v2 = formatDate(val[1]), ival; + if ($td.data('filter')) { + ival = v1 + ' ... ' + v2; + $input.attr('title', ival).val(ival).trigger('input'); + } else { + $input.attr('title', '').val(''); + } + updateSliderText(val[0], val[1]); + if (e.type === 'slide') return; // no searching when sliding only + if (server) { + table.column(i).search($td.data('filter') ? ival : '').draw(); + return; + } + table.draw(); + }; + filter.on({ + set: updateSlider, + slide: updateSlider + }); + } + + // server-side processing will be handled by R (or whatever server + // language you use); the following code is only needed for client-side + // processing + if (server) { + // if a search string has been pre-set, search now + if (searchCol) searchColumn(i, searchCol).draw(); + return; + } + + var customFilter = function(settings, data, dataIndex) { + // there is no way to attach a search function to a specific table, + // and we need to make sure a global search function is not applied to + // all tables (i.e. a range filter in a previous table should not be + // applied to the current table); we use the settings object to + // determine if we want to perform searching on the current table, + // since settings.sTableId will be different to different tables + if (table.settings()[0] !== settings) return true; + // no filter on this column or no need to filter this column + if (typeof filter === 'undefined' || !$td.data('filter')) return true; + + var r = filter.val(), v, r0, r1; + var i_data = function(i) { + if (!colReorderEnabled()) return i; + var order = table.colReorder.order(), k; + for (k = 0; k < order.length; ++k) if (order[k] === i) return k; + return i; // in theory it will never be here... + } + v = data[i_data(i)]; + if (type === 'number' || type === 'integer') { + v = parseFloat(v); + // how to handle NaN? currently exclude these rows + if (isNaN(v)) return(false); + r0 = parseFloat(scaleBack(r[0], scale)) + r1 = parseFloat(scaleBack(r[1], scale)); + if (v >= r0 && v <= r1) return true; + } else if (type === 'date' || type === 'time') { + v = new Date(v); + r0 = new Date(r[0] / scale); r1 = new Date(r[1] / scale); + if (v >= r0 && v <= r1) return true; + } else if (type === 'factor') { + if (r.length === 0 || inArray(v, r)) return true; + } else if (type === 'logical') { + if (r.length === 0) return true; + if (inArray(v === '' ? 'na' : v, r)) return true; + } + return false; + }; + + $.fn.dataTable.ext.search.push(customFilter); + + // search for the preset search strings if it is non-empty + if (searchCol) { + if (inArray(type, ['factor', 'logical'])) { + filter[0].selectize.setValue(JSON.parse(searchCol)); + } else if (type === 'character') { + $input.trigger('input'); + } else if (inArray(type, ['number', 'integer', 'date', 'time'])) { + $input.trigger('change'); + } + } + + }); + + } + + // highlight search keywords + var highlight = function() { + var body = $(table.table().body()); + // removing the old highlighting first + body.unhighlight(); + + // don't highlight the "not found" row, so we get the rows using the api + if (table.rows({ filter: 'applied' }).data().length === 0) return; + // highlight global search keywords + body.highlight($.trim(table.search()).split(/\s+/)); + // then highlight keywords from individual column filters + if (filterRow) filterRow.each(function(i, td) { + var $td = $(td), type = $td.data('type'); + if (type !== 'character') return; + var $input = $td.children('div').first().children('input'); + var column = table.column(i).nodes().to$(), + val = $.trim($input.val()); + if (type !== 'character' || val === '') return; + column.highlight(val.split(/\s+/)); + }); + }; + + if (options.searchHighlight) { + table + .on('draw.dt.dth column-visibility.dt.dth column-reorder.dt.dth', highlight) + .on('destroy', function() { + // remove event handler + table.off('draw.dt.dth column-visibility.dt.dth column-reorder.dt.dth'); + }); + + // Set the option for escaping regex characters in our search string. This will be used + // for all future matching. + jQuery.fn.highlight.options.escapeRegex = (!options.search || !options.search.regex); + + // initial highlight for state saved conditions and initial states + highlight(); + } + + // run the callback function on the table instance + if (typeof data.callback === 'function') data.callback(table); + + // double click to edit the cell, row, column, or all cells + if (data.editable) table.on('dblclick.dt', 'tbody td', function(e) { + // only bring up the editor when the cell itself is dbclicked, and ignore + // other dbclick events bubbled up (e.g. from the ) + if (e.target !== this) return; + var target = [], immediate = false; + switch (data.editable.target) { + case 'cell': + target = [this]; + immediate = true; // edit will take effect immediately + break; + case 'row': + target = table.cells(table.cell(this).index().row, '*').nodes(); + break; + case 'column': + target = table.cells('*', table.cell(this).index().column).nodes(); + break; + case 'all': + target = table.cells().nodes(); + break; + default: + throw 'The editable parameter must be "cell", "row", "column", or "all"'; + } + var disableCols = data.editable.disable ? data.editable.disable.columns : null; + var numericCols = data.editable.numeric; + var areaCols = data.editable.area; + var dateCols = data.editable.date; + for (var i = 0; i < target.length; i++) { + (function(cell, current) { + var $cell = $(cell), html = $cell.html(); + var _cell = table.cell(cell), value = _cell.data(), index = _cell.index().column; + var $input; + if (inArray(index, numericCols)) { + $input = $(''); + } else if (inArray(index, areaCols)) { + $input = $(''); + } else if (inArray(index, dateCols)) { + $input = $(''); + } else { + $input = $(''); + } + if (!immediate) { + $cell.data('input', $input).data('html', html); + $input.attr('title', 'Hit Ctrl+Enter to finish editing, or Esc to cancel'); + } + $input.val(value); + if (inArray(index, disableCols)) { + $input.attr('readonly', '').css('filter', 'invert(25%)'); + } + $cell.empty().append($input); + if (cell === current) $input.focus(); + $input.css('width', '100%'); + + if (immediate) $input.on('blur', function(e) { + var valueNew = $input.val(); + if (valueNew !== value) { + _cell.data(valueNew); + if (HTMLWidgets.shinyMode) { + changeInput('cell_edit', [cellInfo(cell)], 'DT.cellInfo', null, {priority: 'event'}); + } + // for server-side processing, users have to call replaceData() to update the table + if (!server) table.draw(false); + } else { + $cell.html(html); + } + }).on('keyup', function(e) { + // hit Escape to cancel editing + if (e.keyCode === 27) $input.trigger('blur'); + }); + + // bulk edit (row, column, or all) + if (!immediate) $input.on('keyup', function(e) { + var removeInput = function($cell, restore) { + $cell.data('input').remove(); + if (restore) $cell.html($cell.data('html')); + } + if (e.keyCode === 27) { + for (var i = 0; i < target.length; i++) { + removeInput($(target[i]), true); + } + } else if (e.keyCode === 13 && e.ctrlKey) { + // Ctrl + Enter + var cell, $cell, _cell, cellData = []; + for (var i = 0; i < target.length; i++) { + cell = target[i]; $cell = $(cell); _cell = table.cell(cell); + _cell.data($cell.data('input').val()); + HTMLWidgets.shinyMode && cellData.push(cellInfo(cell)); + removeInput($cell, false); + } + if (HTMLWidgets.shinyMode) { + changeInput('cell_edit', cellData, 'DT.cellInfo', null, {priority: "event"}); + } + if (!server) table.draw(false); + } + }); + })(target[i], this); + } + }); + + // interaction with shiny + if (!HTMLWidgets.shinyMode && !crosstalkOptions.group) return; + + var methods = {}; + var shinyData = {}; + + methods.updateCaption = function(caption) { + if (!caption) return; + $table.children('caption').replaceWith(caption); + } + + // register clear functions to remove input values when the table is removed + instance.clearInputs = {}; + + var changeInput = function(id, value, type, noCrosstalk, opts) { + var event = id; + id = el.id + '_' + id; + if (type) id = id + ':' + type; + // do not update if the new value is the same as old value + if (event !== 'cell_edit' && !/_clicked$/.test(event) && shinyData.hasOwnProperty(id) && shinyData[id] === JSON.stringify(value)) + return; + shinyData[id] = JSON.stringify(value); + if (HTMLWidgets.shinyMode && Shiny.setInputValue) { + Shiny.setInputValue(id, value, opts); + if (!instance.clearInputs[id]) instance.clearInputs[id] = function() { + Shiny.setInputValue(id, null); + } + } + + // HACK + if (event === "rows_selected" && !noCrosstalk) { + if (crosstalkOptions.group) { + var keys = crosstalkOptions.key; + var selectedKeys = null; + if (value) { + selectedKeys = []; + for (var i = 0; i < value.length; i++) { + // The value array's contents use 1-based row numbers, so we must + // convert to 0-based before indexing into the keys array. + selectedKeys.push(keys[value[i] - 1]); + } + } + instance.ctselectHandle.set(selectedKeys); + } + } + }; + + var addOne = function(x) { + return x.map(function(i) { return 1 + i; }); + }; + + var unique = function(x) { + var ux = []; + $.each(x, function(i, el){ + if ($.inArray(el, ux) === -1) ux.push(el); + }); + return ux; + } + + // change the row index of a cell + var tweakCellIndex = function(cell) { + var info = cell.index(); + // some cell may not be valid. e.g, #759 + // when using the RowGroup extension, datatables will + // generate the row label and the cells are not part of + // the data thus contain no row/col info + if (info === undefined) + return {row: null, col: null}; + if (server) { + info.row = DT_rows_current[info.row]; + } else { + info.row += 1; + } + return {row: info.row, col: info.column}; + } + + var cleanSelectedValues = function() { + changeInput('rows_selected', []); + changeInput('columns_selected', []); + changeInput('cells_selected', transposeArray2D([]), 'shiny.matrix'); + } + // #828 we should clean the selection on the server-side when the table reloads + cleanSelectedValues(); + + // a flag to indicates if select extension is initialized or not + var flagSelectExt = table.settings()[0]._select !== undefined; + // the Select extension should only be used in the client mode and + // when the selection.mode is set to none + if (data.selection.mode === 'none' && !server && flagSelectExt) { + var updateRowsSelected = function() { + var rows = table.rows({selected: true}); + var selected = []; + $.each(rows.indexes().toArray(), function(i, v) { + selected.push(v + 1); + }); + changeInput('rows_selected', selected); + } + var updateColsSelected = function() { + var columns = table.columns({selected: true}); + changeInput('columns_selected', columns.indexes().toArray()); + } + var updateCellsSelected = function() { + var cells = table.cells({selected: true}); + var selected = []; + cells.every(function() { + var row = this.index().row; + var col = this.index().column; + selected = selected.concat([[row + 1, col]]); + }); + changeInput('cells_selected', transposeArray2D(selected), 'shiny.matrix'); + } + table.on('select deselect', function(e, dt, type, indexes) { + updateRowsSelected(); + updateColsSelected(); + updateCellsSelected(); + }) + } + + var selMode = data.selection.mode, selTarget = data.selection.target; + var selDisable = data.selection.selectable === false; + if (inArray(selMode, ['single', 'multiple'])) { + var selClass = inArray(data.style, ['bootstrap', 'bootstrap4']) ? 'active' : 'selected'; + // selected1: row indices; selected2: column indices + var initSel = function(x) { + if (x === null || typeof x === 'boolean' || selTarget === 'cell') { + return {rows: [], cols: []}; + } else if (selTarget === 'row') { + return {rows: $.makeArray(x), cols: []}; + } else if (selTarget === 'column') { + return {rows: [], cols: $.makeArray(x)}; + } else if (selTarget === 'row+column') { + return {rows: $.makeArray(x.rows), cols: $.makeArray(x.cols)}; + } + } + var selected = data.selection.selected; + var selected1 = initSel(selected).rows, selected2 = initSel(selected).cols; + // selectable should contain either all positive or all non-positive values, not both + // positive values indicate "selectable" while non-positive values means "nonselectable" + // the assertion is performed on R side. (only column indicides could be zero which indicates + // the row name) + var selectable = data.selection.selectable; + var selectable1 = initSel(selectable).rows, selectable2 = initSel(selectable).cols; + + // After users reorder the rows or filter the table, we cannot use the table index + // directly. Instead, we need this function to find out the rows between the two clicks. + // If user filter the table again between the start click and the end click, the behavior + // would be undefined, but it should not be a problem. + var shiftSelRowsIndex = function(start, end) { + var indexes = server ? DT_rows_all : table.rows({ search: 'applied' }).indexes().toArray(); + start = indexes.indexOf(start); end = indexes.indexOf(end); + // if start is larger than end, we need to swap + if (start > end) { + var tmp = end; end = start; start = tmp; + } + return indexes.slice(start, end + 1); + } + + var serverRowIndex = function(clientRowIndex) { + return server ? DT_rows_current[clientRowIndex] : clientRowIndex + 1; + } + + // row, column, or cell selection + var lastClickedRow; + if (inArray(selTarget, ['row', 'row+column'])) { + // Get the current selected rows. It will also + // update the selected1's value based on the current row selection state + // Note we can't put this function inside selectRows() directly, + // the reason is method.selectRows() will override selected1's value but this + // function will add rows to selected1 (keep the existing selection), which is + // inconsistent with column and cell selection. + var selectedRows = function() { + var rows = table.rows('.' + selClass); + var idx = rows.indexes().toArray(); + if (!server) { + selected1 = addOne(idx); + return selected1; + } + idx = idx.map(function(i) { + return DT_rows_current[i]; + }); + selected1 = selMode === 'multiple' ? unique(selected1.concat(idx)) : idx; + return selected1; + } + // Change selected1's value based on selectable1, then refresh the row state + var onlyKeepSelectableRows = function() { + if (selDisable) { // users can't select; useful when only want backend select + selected1 = []; + return; + } + if (selectable1.length === 0) return; + var nonselectable = selectable1[0] <= 0; + if (nonselectable) { + // should make selectable1 positive + selected1 = $(selected1).not(selectable1.map(function(i) { return -i; })).get(); + } else { + selected1 = $(selected1).filter(selectable1).get(); + } + } + // Change selected1's value based on selectable1, then + // refresh the row selection state according to values in selected1 + var selectRows = function(ignoreSelectable) { + if (!ignoreSelectable) onlyKeepSelectableRows(); + table.$('tr.' + selClass).removeClass(selClass); + if (selected1.length === 0) return; + if (server) { + table.rows({page: 'current'}).every(function() { + if (inArray(DT_rows_current[this.index()], selected1)) { + $(this.node()).addClass(selClass); + } + }); + } else { + var selected0 = selected1.map(function(i) { return i - 1; }); + $(table.rows(selected0).nodes()).addClass(selClass); + } + } + table.on('mousedown.dt', 'tbody tr', function(e) { + var $this = $(this), thisRow = table.row(this); + if (selMode === 'multiple') { + if (e.shiftKey && lastClickedRow !== undefined) { + // select or de-select depends on the last clicked row's status + var flagSel = !$this.hasClass(selClass); + var crtClickedRow = serverRowIndex(thisRow.index()); + if (server) { + var rowsIndex = shiftSelRowsIndex(lastClickedRow, crtClickedRow); + // update current page's selClass + rowsIndex.map(function(i) { + var rowIndex = DT_rows_current.indexOf(i); + if (rowIndex >= 0) { + var row = table.row(rowIndex).nodes().to$(); + var flagRowSel = !row.hasClass(selClass); + if (flagSel === flagRowSel) row.toggleClass(selClass); + } + }); + // update selected1 + if (flagSel) { + selected1 = unique(selected1.concat(rowsIndex)); + } else { + selected1 = selected1.filter(function(index) { + return !inArray(index, rowsIndex); + }); + } + } else { + // js starts from 0 + shiftSelRowsIndex(lastClickedRow - 1, crtClickedRow - 1).map(function(value) { + var row = table.row(value).nodes().to$(); + var flagRowSel = !row.hasClass(selClass); + if (flagSel === flagRowSel) row.toggleClass(selClass); + }); + } + e.preventDefault(); + } else { + $this.toggleClass(selClass); + } + } else { + if ($this.hasClass(selClass)) { + $this.removeClass(selClass); + } else { + table.$('tr.' + selClass).removeClass(selClass); + $this.addClass(selClass); + } + } + if (server && !$this.hasClass(selClass)) { + var id = DT_rows_current[thisRow.index()]; + // remove id from selected1 since its class .selected has been removed + if (inArray(id, selected1)) selected1.splice($.inArray(id, selected1), 1); + } + selectedRows(); // update selected1's value based on selClass + selectRows(false); // only keep the selectable rows + changeInput('rows_selected', selected1); + changeInput('row_last_clicked', serverRowIndex(thisRow.index()), null, null, {priority: 'event'}); + lastClickedRow = serverRowIndex(thisRow.index()); + }); + selectRows(false); // in case users have specified pre-selected rows + // restore selected rows after the table is redrawn (e.g. sort/search/page); + // client-side tables will preserve the selections automatically; for + // server-side tables, we have to *real* row indices are in `selected1` + changeInput('rows_selected', selected1); + if (server) table.on('draw.dt', function(e) { selectRows(false); }); + methods.selectRows = function(selected, ignoreSelectable) { + selected1 = $.makeArray(selected); + selectRows(ignoreSelectable); + changeInput('rows_selected', selected1); + } + } + + if (inArray(selTarget, ['column', 'row+column'])) { + if (selTarget === 'row+column') { + $(table.columns().footer()).css('cursor', 'pointer'); + } + // update selected2's value based on selectable2 + var onlyKeepSelectableCols = function() { + if (selDisable) { // users can't select; useful when only want backend select + selected2 = []; + return; + } + if (selectable2.length === 0) return; + var nonselectable = selectable2[0] <= 0; + if (nonselectable) { + // need to make selectable2 positive + selected2 = $(selected2).not(selectable2.map(function(i) { return -i; })).get(); + } else { + selected2 = $(selected2).filter(selectable2).get(); + } + } + // update selected2 and then + // refresh the col selection state according to values in selected2 + var selectCols = function(ignoreSelectable) { + if (!ignoreSelectable) onlyKeepSelectableCols(); + // if selected2 is not a valide index (e.g., larger than the column number) + // table.columns(selected2) will fail and result in a blank table + // this is different from the table.rows(), where the out-of-range indexes + // doesn't affect at all + selected2 = $(selected2).filter(table.columns().indexes()).get(); + table.columns().nodes().flatten().to$().removeClass(selClass); + if (selected2.length > 0) + table.columns(selected2).nodes().flatten().to$().addClass(selClass); + } + var callback = function() { + var colIdx = selTarget === 'column' ? table.cell(this).index().column : + $.inArray(this, table.columns().footer()), + thisCol = $(table.column(colIdx).nodes()); + if (colIdx === -1) return; + if (thisCol.hasClass(selClass)) { + thisCol.removeClass(selClass); + selected2.splice($.inArray(colIdx, selected2), 1); + } else { + if (selMode === 'single') $(table.cells().nodes()).removeClass(selClass); + thisCol.addClass(selClass); + selected2 = selMode === 'single' ? [colIdx] : unique(selected2.concat([colIdx])); + } + selectCols(false); // update selected2 based on selectable + changeInput('columns_selected', selected2); + } + if (selTarget === 'column') { + $(table.table().body()).on('click.dt', 'td', callback); + } else { + $(table.table().footer()).on('click.dt', 'tr th', callback); + } + selectCols(false); // in case users have specified pre-selected columns + changeInput('columns_selected', selected2); + if (server) table.on('draw.dt', function(e) { selectCols(false); }); + methods.selectColumns = function(selected, ignoreSelectable) { + selected2 = $.makeArray(selected); + selectCols(ignoreSelectable); + changeInput('columns_selected', selected2); + } + } + + if (selTarget === 'cell') { + var selected3 = [], selectable3 = []; + if (selected !== null) selected3 = selected; + if (selectable !== null && typeof selectable !== 'boolean') selectable3 = selectable; + var findIndex = function(ij, sel) { + for (var i = 0; i < sel.length; i++) { + if (ij[0] === sel[i][0] && ij[1] === sel[i][1]) return i; + } + return -1; + } + // Change selected3's value based on selectable3, then refresh the cell state + var onlyKeepSelectableCells = function() { + if (selDisable) { // users can't select; useful when only want backend select + selected3 = []; + return; + } + if (selectable3.length === 0) return; + var nonselectable = selectable3[0][0] <= 0; + var out = []; + if (nonselectable) { + selected3.map(function(ij) { + // should make selectable3 positive + if (findIndex([-ij[0], -ij[1]], selectable3) === -1) { out.push(ij); } + }); + } else { + selected3.map(function(ij) { + if (findIndex(ij, selectable3) > -1) { out.push(ij); } + }); + } + selected3 = out; + } + // Change selected3's value based on selectable3, then + // refresh the cell selection state according to values in selected3 + var selectCells = function(ignoreSelectable) { + if (!ignoreSelectable) onlyKeepSelectableCells(); + table.$('td.' + selClass).removeClass(selClass); + if (selected3.length === 0) return; + if (server) { + table.cells({page: 'current'}).every(function() { + var info = tweakCellIndex(this); + if (findIndex([info.row, info.col], selected3) > -1) + $(this.node()).addClass(selClass); + }); + } else { + selected3.map(function(ij) { + $(table.cell(ij[0] - 1, ij[1]).node()).addClass(selClass); + }); + } + }; + table.on('click.dt', 'tbody td', function() { + var $this = $(this), info = tweakCellIndex(table.cell(this)); + if ($this.hasClass(selClass)) { + $this.removeClass(selClass); + selected3.splice(findIndex([info.row, info.col], selected3), 1); + } else { + if (selMode === 'single') $(table.cells().nodes()).removeClass(selClass); + $this.addClass(selClass); + selected3 = selMode === 'single' ? [[info.row, info.col]] : + unique(selected3.concat([[info.row, info.col]])); + } + selectCells(false); // must call this to update selected3 based on selectable3 + changeInput('cells_selected', transposeArray2D(selected3), 'shiny.matrix'); + }); + selectCells(false); // in case users have specified pre-selected columns + changeInput('cells_selected', transposeArray2D(selected3), 'shiny.matrix'); + + if (server) table.on('draw.dt', function(e) { selectCells(false); }); + methods.selectCells = function(selected, ignoreSelectable) { + selected3 = selected ? selected : []; + selectCells(ignoreSelectable); + changeInput('cells_selected', transposeArray2D(selected3), 'shiny.matrix'); + } + } + } + + // expose some table info to Shiny + var updateTableInfo = function(e, settings) { + // TODO: is anyone interested in the page info? + // changeInput('page_info', table.page.info()); + var updateRowInfo = function(id, modifier) { + var idx; + if (server) { + idx = modifier.page === 'current' ? DT_rows_current : DT_rows_all; + } else { + var rows = table.rows($.extend({ + search: 'applied', + page: 'all' + }, modifier)); + idx = addOne(rows.indexes().toArray()); + } + changeInput('rows' + '_' + id, idx); + }; + updateRowInfo('current', {page: 'current'}); + updateRowInfo('all', {}); + } + table.on('draw.dt', updateTableInfo); + updateTableInfo(); + + // state info + table.on('draw.dt column-visibility.dt', function() { + changeInput('state', table.state()); + }); + changeInput('state', table.state()); + + // search info + var updateSearchInfo = function() { + changeInput('search', table.search()); + if (filterRow) changeInput('search_columns', filterRow.toArray().map(function(td) { + return $(td).find('input').first().val(); + })); + } + table.on('draw.dt', updateSearchInfo); + updateSearchInfo(); + + var cellInfo = function(thiz) { + var info = tweakCellIndex(table.cell(thiz)); + info.value = table.cell(thiz).data(); + return info; + } + // the current cell clicked on + table.on('click.dt', 'tbody td', function() { + changeInput('cell_clicked', cellInfo(this), null, null, {priority: 'event'}); + }) + changeInput('cell_clicked', {}); + + // do not trigger table selection when clicking on links unless they have classes + table.on('click.dt', 'tbody td a', function(e) { + if (this.className === '') e.stopPropagation(); + }); + + methods.addRow = function(data, rowname, resetPaging) { + var n = table.columns().indexes().length, d = n - data.length; + if (d === 1) { + data = rowname.concat(data) + } else if (d !== 0) { + console.log(data); + console.log(table.columns().indexes()); + throw 'New data must be of the same length as current data (' + n + ')'; + }; + table.row.add(data).draw(resetPaging); + } + + methods.updateSearch = function(keywords) { + if (keywords.global !== null) + $(table.table().container()).find('input[type=search]').first() + .val(keywords.global).trigger('input'); + var columns = keywords.columns; + if (!filterRow || columns === null) return; + filterRow.toArray().map(function(td, i) { + var v = typeof columns === 'string' ? columns : columns[i]; + if (typeof v === 'undefined') { + console.log('The search keyword for column ' + i + ' is undefined') + return; + } + $(td).find('input').first().val(v); + searchColumn(i, v); + }); + table.draw(); + } + + methods.hideCols = function(hide, reset) { + if (reset) table.columns().visible(true, false); + table.columns(hide).visible(false); + } + + methods.showCols = function(show, reset) { + if (reset) table.columns().visible(false, false); + table.columns(show).visible(true); + } + + methods.colReorder = function(order, origOrder) { + table.colReorder.order(order, origOrder); + } + + methods.selectPage = function(page) { + if (table.page.info().pages < page || page < 1) { + throw 'Selected page is out of range'; + }; + table.page(page - 1).draw(false); + } + + methods.reloadData = function(resetPaging, clearSelection) { + // empty selections first if necessary + if (methods.selectRows && inArray('row', clearSelection)) methods.selectRows([]); + if (methods.selectColumns && inArray('column', clearSelection)) methods.selectColumns([]); + if (methods.selectCells && inArray('cell', clearSelection)) methods.selectCells([]); + table.ajax.reload(null, resetPaging); + } + + // update table filters (set new limits of sliders) + methods.updateFilters = function(newProps) { + // loop through each filter in the filter row + filterRow.each(function(i, td) { + var k = i; + if (filterRow.length > newProps.length) { + if (i === 0) return; // first column is row names + k = i - 1; + } + // Update the filters to reflect the updated data. + // Allow "falsy" (e.g. NULL) to signify a no-op. + if (newProps[k]) { + setFilterProps(td, newProps[k]); + } + }); + }; + + table.shinyMethods = methods; + }, + resize: function(el, width, height, instance) { + if (instance.data) this.renderValue(el, instance.data, instance); + + // dynamically adjust height if fillContainer = TRUE + if (instance.fillContainer) + this.fillAvailableHeight(el, height); + + this.adjustWidth(el); + }, + + // dynamically set the scroll body to fill available height + // (used with fillContainer = TRUE) + fillAvailableHeight: function(el, availableHeight) { + + // see how much of the table is occupied by header/footer elements + // and use that to compute a target scroll body height + var dtWrapper = $(el).find('div.dataTables_wrapper'); + var dtScrollBody = $(el).find($('div.dataTables_scrollBody')); + var framingHeight = dtWrapper.innerHeight() - dtScrollBody.innerHeight(); + var scrollBodyHeight = availableHeight - framingHeight; + + // we need to set `max-height` to none as datatables library now sets this + // to a fixed height, disabling the ability to resize to fill the window, + // as it will be set to a fixed 100px under such circumstances, e.g., RStudio IDE, + // or FlexDashboard + // see https://github.com/rstudio/DT/issues/951#issuecomment-1026464509 + dtScrollBody.css('max-height', 'none'); + // set the height + dtScrollBody.height(scrollBodyHeight + 'px'); + }, + + // adjust the width of columns; remove the hard-coded widths on table and the + // scroll header when scrollX/Y are enabled + adjustWidth: function(el) { + var $el = $(el), table = $el.data('datatable'); + if (table) table.columns.adjust(); + $el.find('.dataTables_scrollHeadInner').css('width', '') + .children('table').css('margin-left', ''); + } +}); + + if (!HTMLWidgets.shinyMode) return; + + Shiny.addCustomMessageHandler('datatable-calls', function(data) { + var id = data.id; + var el = document.getElementById(id); + var table = el ? $(el).data('datatable') : null; + if (!table) { + console.log("Couldn't find table with id " + id); + return; + } + + var methods = table.shinyMethods, call = data.call; + if (methods[call.method]) { + methods[call.method].apply(table, call.args); + } else { + console.log("Unknown method " + call.method); + } + }); + +})(); diff --git a/public/site_libs/datatables-css-0.0.0/datatables-crosstalk.css b/public/site_libs/datatables-css-0.0.0/datatables-crosstalk.css new file mode 100644 index 00000000..bd1159c8 --- /dev/null +++ b/public/site_libs/datatables-css-0.0.0/datatables-crosstalk.css @@ -0,0 +1,32 @@ +.dt-crosstalk-fade { + opacity: 0.2; +} + +html body div.DTS div.dataTables_scrollBody { + background: none; +} + + +/* +Fix https://github.com/rstudio/DT/issues/563 +If the `table.display` is set to "block" (e.g., pkgdown), the browser will display +datatable objects strangely. The search panel and the page buttons will still be +in full-width but the table body will be "compact" and shorter. +In therory, having this attributes will affect `dom="t"` +with `display: block` users. But in reality, there should be no one. +We may remove the below lines in the future if the upstream agree to have this there. +See https://github.com/DataTables/DataTablesSrc/issues/160 +*/ + +table.dataTable { + display: table; +} + + +/* +When DTOutput(fill = TRUE), it receives a .html-fill-item class (via htmltools::bindFillRole()), which effectively amounts to `flex: 1 1 auto`. That's mostly fine, but the case where `fillContainer=TRUE`+`height:auto`+`flex-basis:auto` and the container (e.g., a bslib::card()) doesn't have a defined height is a bit problematic since the table wants to fit the parent but the parent wants to fit the table, which results pretty small table height (maybe because there is a minimum height somewhere?). It seems better in this case to impose a 400px height default for the table, which we can do by setting `flex-basis` to 400px (the table is still allowed to grow/shrink when the container has an opinionated height). +*/ + +.html-fill-container > .html-fill-item.datatables { + flex-basis: 400px; +} diff --git a/public/site_libs/dt-core-1.13.4/css/jquery.dataTables.extra.css b/public/site_libs/dt-core-1.13.4/css/jquery.dataTables.extra.css new file mode 100644 index 00000000..b2dd141f --- /dev/null +++ b/public/site_libs/dt-core-1.13.4/css/jquery.dataTables.extra.css @@ -0,0 +1,28 @@ +/* Selected rows/cells */ +table.dataTable tr.selected td, table.dataTable td.selected { + background-color: #b0bed9 !important; +} +/* In case of scrollX/Y or FixedHeader */ +.dataTables_scrollBody .dataTables_sizing { + visibility: hidden; +} + +/* The datatables' theme CSS file doesn't define +the color but with white background. It leads to an issue that +when the HTML's body color is set to 'white', the user can't +see the text since the background is white. One case happens in the +RStudio's IDE when inline viewing the DT table inside an Rmd file, +if the IDE theme is set to "Cobalt". + +See https://github.com/rstudio/DT/issues/447 for more info + +This fixes should have little side-effects because all the other elements +of the default theme use the #333 font color. + +TODO: The upstream may use relative colors for both the table background +and the color. It means the table can display well without this patch +then. At that time, we need to remove the below CSS attributes. +*/ +div.datatables { + color: #333; +} diff --git a/public/site_libs/dt-core-1.13.4/css/jquery.dataTables.min.css b/public/site_libs/dt-core-1.13.4/css/jquery.dataTables.min.css new file mode 100644 index 00000000..aff1ca67 --- /dev/null +++ b/public/site_libs/dt-core-1.13.4/css/jquery.dataTables.min.css @@ -0,0 +1 @@ +:root{--dt-row-selected: 13, 110, 253;--dt-row-selected-text: 255, 255, 255;--dt-row-selected-link: 9, 10, 11}table.dataTable td.dt-control{text-align:center;cursor:pointer}table.dataTable td.dt-control:before{height:1em;width:1em;margin-top:-9px;display:inline-block;color:white;border:.15em solid white;border-radius:1em;box-shadow:0 0 .2em #444;box-sizing:content-box;text-align:center;text-indent:0 !important;font-family:"Courier New",Courier,monospace;line-height:1em;content:"+";background-color:#31b131}table.dataTable tr.dt-hasChild td.dt-control:before{content:"-";background-color:#d33333}table.dataTable thead>tr>th.sorting,table.dataTable thead>tr>th.sorting_asc,table.dataTable thead>tr>th.sorting_desc,table.dataTable thead>tr>th.sorting_asc_disabled,table.dataTable thead>tr>th.sorting_desc_disabled,table.dataTable thead>tr>td.sorting,table.dataTable thead>tr>td.sorting_asc,table.dataTable thead>tr>td.sorting_desc,table.dataTable thead>tr>td.sorting_asc_disabled,table.dataTable thead>tr>td.sorting_desc_disabled{cursor:pointer;position:relative;padding-right:26px}table.dataTable thead>tr>th.sorting:before,table.dataTable thead>tr>th.sorting:after,table.dataTable thead>tr>th.sorting_asc:before,table.dataTable thead>tr>th.sorting_asc:after,table.dataTable thead>tr>th.sorting_desc:before,table.dataTable thead>tr>th.sorting_desc:after,table.dataTable thead>tr>th.sorting_asc_disabled:before,table.dataTable thead>tr>th.sorting_asc_disabled:after,table.dataTable thead>tr>th.sorting_desc_disabled:before,table.dataTable thead>tr>th.sorting_desc_disabled:after,table.dataTable thead>tr>td.sorting:before,table.dataTable thead>tr>td.sorting:after,table.dataTable thead>tr>td.sorting_asc:before,table.dataTable thead>tr>td.sorting_asc:after,table.dataTable thead>tr>td.sorting_desc:before,table.dataTable thead>tr>td.sorting_desc:after,table.dataTable thead>tr>td.sorting_asc_disabled:before,table.dataTable thead>tr>td.sorting_asc_disabled:after,table.dataTable thead>tr>td.sorting_desc_disabled:before,table.dataTable thead>tr>td.sorting_desc_disabled:after{position:absolute;display:block;opacity:.125;right:10px;line-height:9px;font-size:.8em}table.dataTable thead>tr>th.sorting:before,table.dataTable thead>tr>th.sorting_asc:before,table.dataTable thead>tr>th.sorting_desc:before,table.dataTable thead>tr>th.sorting_asc_disabled:before,table.dataTable thead>tr>th.sorting_desc_disabled:before,table.dataTable thead>tr>td.sorting:before,table.dataTable thead>tr>td.sorting_asc:before,table.dataTable thead>tr>td.sorting_desc:before,table.dataTable thead>tr>td.sorting_asc_disabled:before,table.dataTable thead>tr>td.sorting_desc_disabled:before{bottom:50%;content:"▲";content:"▲"/""}table.dataTable thead>tr>th.sorting:after,table.dataTable thead>tr>th.sorting_asc:after,table.dataTable thead>tr>th.sorting_desc:after,table.dataTable thead>tr>th.sorting_asc_disabled:after,table.dataTable thead>tr>th.sorting_desc_disabled:after,table.dataTable thead>tr>td.sorting:after,table.dataTable thead>tr>td.sorting_asc:after,table.dataTable thead>tr>td.sorting_desc:after,table.dataTable thead>tr>td.sorting_asc_disabled:after,table.dataTable thead>tr>td.sorting_desc_disabled:after{top:50%;content:"▼";content:"▼"/""}table.dataTable thead>tr>th.sorting_asc:before,table.dataTable thead>tr>th.sorting_desc:after,table.dataTable thead>tr>td.sorting_asc:before,table.dataTable thead>tr>td.sorting_desc:after{opacity:.6}table.dataTable thead>tr>th.sorting_desc_disabled:after,table.dataTable thead>tr>th.sorting_asc_disabled:before,table.dataTable thead>tr>td.sorting_desc_disabled:after,table.dataTable thead>tr>td.sorting_asc_disabled:before{display:none}table.dataTable thead>tr>th:active,table.dataTable thead>tr>td:active{outline:none}div.dataTables_scrollBody>table.dataTable>thead>tr>th:before,div.dataTables_scrollBody>table.dataTable>thead>tr>th:after,div.dataTables_scrollBody>table.dataTable>thead>tr>td:before,div.dataTables_scrollBody>table.dataTable>thead>tr>td:after{display:none}div.dataTables_processing{position:absolute;top:50%;left:50%;width:200px;margin-left:-100px;margin-top:-26px;text-align:center;padding:2px}div.dataTables_processing>div:last-child{position:relative;width:80px;height:15px;margin:1em auto}div.dataTables_processing>div:last-child>div{position:absolute;top:0;width:13px;height:13px;border-radius:50%;background:rgb(13, 110, 253);background:rgb(var(--dt-row-selected));animation-timing-function:cubic-bezier(0, 1, 1, 0)}div.dataTables_processing>div:last-child>div:nth-child(1){left:8px;animation:datatables-loader-1 .6s infinite}div.dataTables_processing>div:last-child>div:nth-child(2){left:8px;animation:datatables-loader-2 .6s infinite}div.dataTables_processing>div:last-child>div:nth-child(3){left:32px;animation:datatables-loader-2 .6s infinite}div.dataTables_processing>div:last-child>div:nth-child(4){left:56px;animation:datatables-loader-3 .6s infinite}@keyframes datatables-loader-1{0%{transform:scale(0)}100%{transform:scale(1)}}@keyframes datatables-loader-3{0%{transform:scale(1)}100%{transform:scale(0)}}@keyframes datatables-loader-2{0%{transform:translate(0, 0)}100%{transform:translate(24px, 0)}}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}table.dataTable th.dt-left,table.dataTable td.dt-left{text-align:left}table.dataTable th.dt-center,table.dataTable td.dt-center,table.dataTable td.dataTables_empty{text-align:center}table.dataTable th.dt-right,table.dataTable td.dt-right{text-align:right}table.dataTable th.dt-justify,table.dataTable td.dt-justify{text-align:justify}table.dataTable th.dt-nowrap,table.dataTable td.dt-nowrap{white-space:nowrap}table.dataTable thead th,table.dataTable thead td,table.dataTable tfoot th,table.dataTable tfoot td{text-align:left}table.dataTable thead th.dt-head-left,table.dataTable thead td.dt-head-left,table.dataTable tfoot th.dt-head-left,table.dataTable tfoot td.dt-head-left{text-align:left}table.dataTable thead th.dt-head-center,table.dataTable thead td.dt-head-center,table.dataTable tfoot th.dt-head-center,table.dataTable tfoot td.dt-head-center{text-align:center}table.dataTable thead th.dt-head-right,table.dataTable thead td.dt-head-right,table.dataTable tfoot th.dt-head-right,table.dataTable tfoot td.dt-head-right{text-align:right}table.dataTable thead th.dt-head-justify,table.dataTable thead td.dt-head-justify,table.dataTable tfoot th.dt-head-justify,table.dataTable tfoot td.dt-head-justify{text-align:justify}table.dataTable thead th.dt-head-nowrap,table.dataTable thead td.dt-head-nowrap,table.dataTable tfoot th.dt-head-nowrap,table.dataTable tfoot td.dt-head-nowrap{white-space:nowrap}table.dataTable tbody th.dt-body-left,table.dataTable tbody td.dt-body-left{text-align:left}table.dataTable tbody th.dt-body-center,table.dataTable tbody td.dt-body-center{text-align:center}table.dataTable tbody th.dt-body-right,table.dataTable tbody td.dt-body-right{text-align:right}table.dataTable tbody th.dt-body-justify,table.dataTable tbody td.dt-body-justify{text-align:justify}table.dataTable tbody th.dt-body-nowrap,table.dataTable tbody td.dt-body-nowrap{white-space:nowrap}table.dataTable{width:100%;margin:0 auto;clear:both;border-collapse:separate;border-spacing:0}table.dataTable thead th,table.dataTable tfoot th{font-weight:bold}table.dataTable thead th,table.dataTable thead td{padding:10px;border-bottom:1px solid rgba(0, 0, 0, 0.3)}table.dataTable thead th:active,table.dataTable thead td:active{outline:none}table.dataTable tfoot th,table.dataTable tfoot td{padding:10px 10px 6px 10px;border-top:1px solid rgba(0, 0, 0, 0.3)}table.dataTable tbody tr{background-color:transparent}table.dataTable tbody tr.selected>*{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.9);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.9);color:rgb(255, 255, 255);color:rgb(var(--dt-row-selected-text))}table.dataTable tbody tr.selected a{color:rgb(9, 10, 11);color:rgb(var(--dt-row-selected-link))}table.dataTable tbody th,table.dataTable tbody td{padding:8px 10px}table.dataTable.row-border tbody th,table.dataTable.row-border tbody td,table.dataTable.display tbody th,table.dataTable.display tbody td{border-top:1px solid rgba(0, 0, 0, 0.15)}table.dataTable.row-border tbody tr:first-child th,table.dataTable.row-border tbody tr:first-child td,table.dataTable.display tbody tr:first-child th,table.dataTable.display tbody tr:first-child td{border-top:none}table.dataTable.cell-border tbody th,table.dataTable.cell-border tbody td{border-top:1px solid rgba(0, 0, 0, 0.15);border-right:1px solid rgba(0, 0, 0, 0.15)}table.dataTable.cell-border tbody tr th:first-child,table.dataTable.cell-border tbody tr td:first-child{border-left:1px solid rgba(0, 0, 0, 0.15)}table.dataTable.cell-border tbody tr:first-child th,table.dataTable.cell-border tbody tr:first-child td{border-top:none}table.dataTable.stripe>tbody>tr.odd>*,table.dataTable.display>tbody>tr.odd>*{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.023)}table.dataTable.stripe>tbody>tr.odd.selected>*,table.dataTable.display>tbody>tr.odd.selected>*{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.923);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 0.923))}table.dataTable.hover>tbody>tr:hover>*,table.dataTable.display>tbody>tr:hover>*{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.035)}table.dataTable.hover>tbody>tr.selected:hover>*,table.dataTable.display>tbody>tr.selected:hover>*{box-shadow:inset 0 0 0 9999px #0d6efd !important;box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 1)) !important}table.dataTable.order-column>tbody tr>.sorting_1,table.dataTable.order-column>tbody tr>.sorting_2,table.dataTable.order-column>tbody tr>.sorting_3,table.dataTable.display>tbody tr>.sorting_1,table.dataTable.display>tbody tr>.sorting_2,table.dataTable.display>tbody tr>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.019)}table.dataTable.order-column>tbody tr.selected>.sorting_1,table.dataTable.order-column>tbody tr.selected>.sorting_2,table.dataTable.order-column>tbody tr.selected>.sorting_3,table.dataTable.display>tbody tr.selected>.sorting_1,table.dataTable.display>tbody tr.selected>.sorting_2,table.dataTable.display>tbody tr.selected>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.919);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 0.919))}table.dataTable.display>tbody>tr.odd>.sorting_1,table.dataTable.order-column.stripe>tbody>tr.odd>.sorting_1{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.054)}table.dataTable.display>tbody>tr.odd>.sorting_2,table.dataTable.order-column.stripe>tbody>tr.odd>.sorting_2{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.047)}table.dataTable.display>tbody>tr.odd>.sorting_3,table.dataTable.order-column.stripe>tbody>tr.odd>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.039)}table.dataTable.display>tbody>tr.odd.selected>.sorting_1,table.dataTable.order-column.stripe>tbody>tr.odd.selected>.sorting_1{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.954);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 0.954))}table.dataTable.display>tbody>tr.odd.selected>.sorting_2,table.dataTable.order-column.stripe>tbody>tr.odd.selected>.sorting_2{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.947);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 0.947))}table.dataTable.display>tbody>tr.odd.selected>.sorting_3,table.dataTable.order-column.stripe>tbody>tr.odd.selected>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.939);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 0.939))}table.dataTable.display>tbody>tr.even>.sorting_1,table.dataTable.order-column.stripe>tbody>tr.even>.sorting_1{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.019)}table.dataTable.display>tbody>tr.even>.sorting_2,table.dataTable.order-column.stripe>tbody>tr.even>.sorting_2{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.011)}table.dataTable.display>tbody>tr.even>.sorting_3,table.dataTable.order-column.stripe>tbody>tr.even>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.003)}table.dataTable.display>tbody>tr.even.selected>.sorting_1,table.dataTable.order-column.stripe>tbody>tr.even.selected>.sorting_1{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.919);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 0.919))}table.dataTable.display>tbody>tr.even.selected>.sorting_2,table.dataTable.order-column.stripe>tbody>tr.even.selected>.sorting_2{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.911);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 0.911))}table.dataTable.display>tbody>tr.even.selected>.sorting_3,table.dataTable.order-column.stripe>tbody>tr.even.selected>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.903);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 0.903))}table.dataTable.display tbody tr:hover>.sorting_1,table.dataTable.order-column.hover tbody tr:hover>.sorting_1{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.082)}table.dataTable.display tbody tr:hover>.sorting_2,table.dataTable.order-column.hover tbody tr:hover>.sorting_2{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.074)}table.dataTable.display tbody tr:hover>.sorting_3,table.dataTable.order-column.hover tbody tr:hover>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(0, 0, 0, 0.062)}table.dataTable.display tbody tr:hover.selected>.sorting_1,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_1{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.982);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 0.982))}table.dataTable.display tbody tr:hover.selected>.sorting_2,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_2{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.974);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 0.974))}table.dataTable.display tbody tr:hover.selected>.sorting_3,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_3{box-shadow:inset 0 0 0 9999px rgba(13, 110, 253, 0.962);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected, 0.962))}table.dataTable.no-footer{border-bottom:1px solid rgba(0, 0, 0, 0.3)}table.dataTable.compact thead th,table.dataTable.compact thead td,table.dataTable.compact tfoot th,table.dataTable.compact tfoot td,table.dataTable.compact tbody th,table.dataTable.compact tbody td{padding:4px}table.dataTable th,table.dataTable td{box-sizing:content-box}.dataTables_wrapper{position:relative;clear:both}.dataTables_wrapper .dataTables_length{float:left}.dataTables_wrapper .dataTables_length select{border:1px solid #aaa;border-radius:3px;padding:5px;background-color:transparent;padding:4px}.dataTables_wrapper .dataTables_filter{float:right;text-align:right}.dataTables_wrapper .dataTables_filter input{border:1px solid #aaa;border-radius:3px;padding:5px;background-color:transparent;margin-left:3px}.dataTables_wrapper .dataTables_info{clear:both;float:left;padding-top:.755em}.dataTables_wrapper .dataTables_paginate{float:right;text-align:right;padding-top:.25em}.dataTables_wrapper .dataTables_paginate .paginate_button{box-sizing:border-box;display:inline-block;min-width:1.5em;padding:.5em 1em;margin-left:2px;text-align:center;text-decoration:none !important;cursor:pointer;color:inherit !important;border:1px solid transparent;border-radius:2px;background:transparent}.dataTables_wrapper .dataTables_paginate .paginate_button.current,.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover{color:inherit !important;border:1px solid rgba(0, 0, 0, 0.3);background-color:rgba(230, 230, 230, 0.1);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(230, 230, 230, 0.1)), color-stop(100%, rgba(0, 0, 0, 0.1)));background:-webkit-linear-gradient(top, rgba(230, 230, 230, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:-moz-linear-gradient(top, rgba(230, 230, 230, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:-ms-linear-gradient(top, rgba(230, 230, 230, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:-o-linear-gradient(top, rgba(230, 230, 230, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:linear-gradient(to bottom, rgba(230, 230, 230, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button.disabled,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active{cursor:default;color:#666 !important;border:1px solid transparent;background:transparent;box-shadow:none}.dataTables_wrapper .dataTables_paginate .paginate_button:hover{color:white !important;border:1px solid #111;background-color:#585858;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));background:-webkit-linear-gradient(top, #585858 0%, #111 100%);background:-moz-linear-gradient(top, #585858 0%, #111 100%);background:-ms-linear-gradient(top, #585858 0%, #111 100%);background:-o-linear-gradient(top, #585858 0%, #111 100%);background:linear-gradient(to bottom, #585858 0%, #111 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button:active{outline:none;background-color:#2b2b2b;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));background:-webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);box-shadow:inset 0 0 3px #111}.dataTables_wrapper .dataTables_paginate .ellipsis{padding:0 1em}.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter,.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_processing,.dataTables_wrapper .dataTables_paginate{color:inherit}.dataTables_wrapper .dataTables_scroll{clear:both}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody{-webkit-overflow-scrolling:touch}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>th,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>td,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>th,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>td{vertical-align:middle}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>th>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>td>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>th>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>td>div.dataTables_sizing{height:0;overflow:hidden;margin:0 !important;padding:0 !important}.dataTables_wrapper.no-footer .dataTables_scrollBody{border-bottom:1px solid rgba(0, 0, 0, 0.3)}.dataTables_wrapper.no-footer div.dataTables_scrollHead table.dataTable,.dataTables_wrapper.no-footer div.dataTables_scrollBody>table{border-bottom:none}.dataTables_wrapper:after{visibility:hidden;display:block;content:"";clear:both;height:0}@media screen and (max-width: 767px){.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_paginate{float:none;text-align:center}.dataTables_wrapper .dataTables_paginate{margin-top:.5em}}@media screen and (max-width: 640px){.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter{float:none;text-align:center}.dataTables_wrapper .dataTables_filter{margin-top:.5em}} diff --git a/public/site_libs/dt-core-1.13.4/js/jquery.dataTables.min.js b/public/site_libs/dt-core-1.13.4/js/jquery.dataTables.min.js new file mode 100644 index 00000000..c89263c6 --- /dev/null +++ b/public/site_libs/dt-core-1.13.4/js/jquery.dataTables.min.js @@ -0,0 +1,4 @@ +/*! DataTables 1.13.4 + * ©2008-2023 SpryMedia Ltd - datatables.net/license + */ +!function(n){"use strict";var a;"function"==typeof define&&define.amd?define(["jquery"],function(t){return n(t,window,document)}):"object"==typeof exports?(a=require("jquery"),"undefined"!=typeof window?module.exports=function(t,e){return t=t||window,e=e||a(t),n(e,t,t.document)}:n(a,window,window.document)):window.DataTable=n(jQuery,window,document)}(function(P,j,y,N){"use strict";function d(t){var e=parseInt(t,10);return!isNaN(e)&&isFinite(t)?e:null}function l(t,e,n){var a=typeof t,r="string"==a;return"number"==a||"bigint"==a||!!h(t)||(e&&r&&(t=G(t,e)),n&&r&&(t=t.replace(q,"")),!isNaN(parseFloat(t))&&isFinite(t))}function a(t,e,n){var a;return!!h(t)||(h(a=t)||"string"==typeof a)&&!!l(t.replace(V,""),e,n)||null}function m(t,e,n,a){var r=[],o=0,i=e.length;if(a!==N)for(;o").appendTo(l)),h.nTHead=n[0],l.children("tbody")),n=(0===a.length&&(a=P("").insertAfter(n)),h.nTBody=a[0],l.children("tfoot"));if(0===(n=0===n.length&&0").appendTo(l):n).length||0===n.children().length?l.addClass(p.sNoFooter):0/g,X=/^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/,J=new RegExp("(\\"+["/",".","*","+","?","|","(",")","[","]","{","}","\\","$","^","-"].join("|\\")+")","g"),q=/['\u00A0,$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfkɃΞ]/gi,h=function(t){return!t||!0===t||"-"===t},G=function(t,e){return c[e]||(c[e]=new RegExp(Ot(e),"g")),"string"==typeof t&&"."!==e?t.replace(/\./g,"").replace(c[e],"."):t},H=function(t,e,n){var a=[],r=0,o=t.length;if(n!==N)for(;r").css({position:"fixed",top:0,left:-1*P(j).scrollLeft(),height:1,width:1,overflow:"hidden"}).append(P("
").css({position:"absolute",top:1,left:1,width:100,overflow:"scroll"}).append(P("
").css({width:"100%",height:10}))).appendTo("body")).children()).children(),e.barWidth=a[0].offsetWidth-a[0].clientWidth,e.bScrollOversize=100===r[0].offsetWidth&&100!==a[0].clientWidth,e.bScrollbarLeft=1!==Math.round(r.offset().left),e.bBounding=!!n[0].getBoundingClientRect().width,n.remove()),P.extend(t.oBrowser,w.__browser),t.oScroll.iBarWidth=w.__browser.barWidth}function et(t,e,n,a,r,o){var i,l=a,s=!1;for(n!==N&&(i=n,s=!0);l!==r;)t.hasOwnProperty(l)&&(i=s?e(i,t[l],l,t):t[l],s=!0,l+=o);return i}function nt(t,e){var n=w.defaults.column,a=t.aoColumns.length,n=P.extend({},w.models.oColumn,n,{nTh:e||y.createElement("th"),sTitle:n.sTitle||(e?e.innerHTML:""),aDataSort:n.aDataSort||[a],mData:n.mData||a,idx:a}),n=(t.aoColumns.push(n),t.aoPreSearchCols);n[a]=P.extend({},w.models.oSearch,n[a]),at(t,a,P(e).data())}function at(t,e,n){function a(t){return"string"==typeof t&&-1!==t.indexOf("@")}var e=t.aoColumns[e],r=t.oClasses,o=P(e.nTh),i=(!e.sWidthOrig&&(e.sWidthOrig=o.attr("width")||null,u=(o.attr("style")||"").match(/width:\s*(\d+[pxem%]+)/))&&(e.sWidthOrig=u[1]),n!==N&&null!==n&&(Q(n),C(w.defaults.column,n,!0),n.mDataProp===N||n.mData||(n.mData=n.mDataProp),n.sType&&(e._sManualType=n.sType),n.className&&!n.sClass&&(n.sClass=n.className),n.sClass&&o.addClass(n.sClass),u=e.sClass,P.extend(e,n),F(e,n,"sWidth","sWidthOrig"),u!==e.sClass&&(e.sClass=u+" "+e.sClass),n.iDataSort!==N&&(e.aDataSort=[n.iDataSort]),F(e,n,"aDataSort")),e.mData),l=A(i),s=e.mRender?A(e.mRender):null,u=(e._bAttrSrc=P.isPlainObject(i)&&(a(i.sort)||a(i.type)||a(i.filter)),e._setter=null,e.fnGetData=function(t,e,n){var a=l(t,e,N,n);return s&&e?s(a,e,t,n):a},e.fnSetData=function(t,e,n){return b(i)(t,e,n)},"number"==typeof i||e._isArrayHost||(t._rowReadObject=!0),t.oFeatures.bSort||(e.bSortable=!1,o.addClass(r.sSortableNone)),-1!==P.inArray("asc",e.asSorting)),n=-1!==P.inArray("desc",e.asSorting);e.bSortable&&(u||n)?u&&!n?(e.sSortingClass=r.sSortableAsc,e.sSortingClassJUI=r.sSortJUIAscAllowed):!u&&n?(e.sSortingClass=r.sSortableDesc,e.sSortingClassJUI=r.sSortJUIDescAllowed):(e.sSortingClass=r.sSortable,e.sSortingClassJUI=r.sSortJUI):(e.sSortingClass=r.sSortableNone,e.sSortingClassJUI="")}function O(t){if(!1!==t.oFeatures.bAutoWidth){var e=t.aoColumns;ee(t);for(var n=0,a=e.length;ne&&t[r]--;-1!=a&&n===N&&t.splice(a,1)}function bt(n,a,t,e){function r(t,e){for(;t.childNodes.length;)t.removeChild(t.firstChild);t.innerHTML=S(n,a,e,"display")}var o,i,l=n.aoData[a];if("dom"!==t&&(t&&"auto"!==t||"dom"!==l.src)){var s=l.anCells;if(s)if(e!==N)r(s[e],e);else for(o=0,i=s.length;o").appendTo(r)),c=0,f=s.length;c=s.fnRecordsDisplay()?0:l,s.iInitDisplayStart=-1);var n=R(t,"aoPreDrawCallback","preDraw",[t]);if(-1!==P.inArray(!1,n))D(t,!1);else{var a=[],r=0,o=t.asStripeClasses,i=o.length,l=t.oLanguage,s="ssp"==E(t),u=t.aiDisplay,n=t._iDisplayStart,c=t.fnDisplayEnd();if(t.bDrawing=!0,t.bDeferLoading)t.bDeferLoading=!1,t.iDraw++,D(t,!1);else if(s){if(!t.bDestroying&&!e)return void xt(t)}else t.iDraw++;if(0!==u.length)for(var f=s?t.aoData.length:c,d=s?0:n;d",{class:i?o[0]:""}).append(P("",{valign:"top",colSpan:T(t),class:t.oClasses.sRowEmpty}).html(e))[0]}R(t,"aoHeaderCallback","header",[P(t.nTHead).children("tr")[0],ht(t),n,c,u]),R(t,"aoFooterCallback","footer",[P(t.nTFoot).children("tr")[0],ht(t),n,c,u]);s=P(t.nTBody);s.children().detach(),s.append(P(a)),R(t,"aoDrawCallback","draw",[t]),t.bSorted=!1,t.bFiltered=!1,t.bDrawing=!1}}function u(t,e){var n=t.oFeatures,a=n.bSort,n=n.bFilter;a&&ie(t),n?Rt(t,t.oPreviousSearch):t.aiDisplay=t.aiDisplayMaster.slice(),!0!==e&&(t._iDisplayStart=0),t._drawHold=e,v(t),t._drawHold=!1}function _t(t){for(var e,n,a,r,o,i,l,s=t.oClasses,u=P(t.nTable),u=P("
").insertBefore(u),c=t.oFeatures,f=P("
",{id:t.sTableId+"_wrapper",class:s.sWrapper+(t.nTFoot?"":" "+s.sNoFooter)}),d=(t.nHolding=u[0],t.nTableWrapper=f[0],t.nTableReinsertBefore=t.nTable.nextSibling,t.sDom.split("")),h=0;h")[0],"'"==(r=d[h+1])||'"'==r){for(o="",i=2;d[h+i]!=r;)o+=d[h+i],i++;"H"==o?o=s.sJUIHeader:"F"==o&&(o=s.sJUIFooter),-1!=o.indexOf(".")?(l=o.split("."),a.id=l[0].substr(1,l[0].length-1),a.className=l[1]):"#"==o.charAt(0)?a.id=o.substr(1,o.length-1):a.className=o,h+=i}f.append(a),f=P(a)}else if(">"==n)f=f.parent();else if("l"==n&&c.bPaginate&&c.bLengthChange)e=$t(t);else if("f"==n&&c.bFilter)e=Lt(t);else if("r"==n&&c.bProcessing)e=Zt(t);else if("t"==n)e=Kt(t);else if("i"==n&&c.bInfo)e=Ut(t);else if("p"==n&&c.bPaginate)e=zt(t);else if(0!==w.ext.feature.length)for(var p=w.ext.feature,g=0,b=p.length;g',s=(s=r.sSearch).match(/_INPUT_/)?s.replace("_INPUT_",l):s+l,l=P("
",{id:i.f?null:a+"_filter",class:t.sFilter}).append(P("
").addClass(t.sLength);return a.aanFeatures.l||(c[0].id=e+"_length"),c.children().append(a.oLanguage.sLengthMenu.replace("_MENU_",l[0].outerHTML)),P("select",c).val(a._iDisplayLength).on("change.DT",function(t){Gt(a,P(this).val()),v(a)}),P(a.nTable).on("length.dt.DT",function(t,e,n){a===e&&P("select",c).val(n)}),c[0]}function zt(t){function c(t){v(t)}var e=t.sPaginationType,f=w.ext.pager[e],d="function"==typeof f,e=P("
").addClass(t.oClasses.sPaging+e)[0],h=t.aanFeatures;return d||f.fnInit(t,e,c),h.p||(e.id=t.sTableId+"_paginate",t.aoDrawCallback.push({fn:function(t){if(d)for(var e=t._iDisplayStart,n=t._iDisplayLength,a=t.fnRecordsDisplay(),r=-1===n,o=r?0:Math.ceil(e/n),i=r?1:Math.ceil(a/n),l=f(o,i),s=0,u=h.p.length;s",{id:t.aanFeatures.r?null:t.sTableId+"_processing",class:t.oClasses.sProcessing,role:"status"}).html(t.oLanguage.sProcessing).append("
").insertBefore(t.nTable)[0]}function D(t,e){t.oFeatures.bProcessing&&P(t.aanFeatures.r).css("display",e?"block":"none"),R(t,null,"processing",[t,e])}function Kt(t){var e,n,a,r,o,i,l,s,u,c,f,d,h=P(t.nTable),p=t.oScroll;return""===p.sX&&""===p.sY?t.nTable:(e=p.sX,n=p.sY,a=t.oClasses,o=(r=h.children("caption")).length?r[0]._captionSide:null,s=P(h[0].cloneNode(!1)),i=P(h[0].cloneNode(!1)),u=function(t){return t?M(t):null},(l=h.children("tfoot")).length||(l=null),s=P(f="
",{class:a.sScrollWrapper}).append(P(f,{class:a.sScrollHead}).css({overflow:"hidden",position:"relative",border:0,width:e?u(e):"100%"}).append(P(f,{class:a.sScrollHeadInner}).css({"box-sizing":"content-box",width:p.sXInner||"100%"}).append(s.removeAttr("id").css("margin-left",0).append("top"===o?r:null).append(h.children("thead"))))).append(P(f,{class:a.sScrollBody}).css({position:"relative",overflow:"auto",width:u(e)}).append(h)),l&&s.append(P(f,{class:a.sScrollFoot}).css({overflow:"hidden",border:0,width:e?u(e):"100%"}).append(P(f,{class:a.sScrollFootInner}).append(i.removeAttr("id").css("margin-left",0).append("bottom"===o?r:null).append(h.children("tfoot"))))),u=s.children(),c=u[0],f=u[1],d=l?u[2]:null,e&&P(f).on("scroll.DT",function(t){var e=this.scrollLeft;c.scrollLeft=e,l&&(d.scrollLeft=e)}),P(f).css("max-height",n),p.bCollapse||P(f).css("height",n),t.nScrollHead=c,t.nScrollBody=f,t.nScrollFoot=d,t.aoDrawCallback.push({fn:Qt,sName:"scrolling"}),s[0])}function Qt(n){function t(t){(t=t.style).paddingTop="0",t.paddingBottom="0",t.borderTopWidth="0",t.borderBottomWidth="0",t.height=0}var e,a,r,o,i,l=n.oScroll,s=l.sX,u=l.sXInner,c=l.sY,l=l.iBarWidth,f=P(n.nScrollHead),d=f[0].style,h=f.children("div"),p=h[0].style,h=h.children("table"),g=n.nScrollBody,b=P(g),m=g.style,S=P(n.nScrollFoot).children("div"),v=S.children("table"),y=P(n.nTHead),D=P(n.nTable),_=D[0],w=_.style,C=n.nTFoot?P(n.nTFoot):null,T=n.oBrowser,x=T.bScrollOversize,A=(H(n.aoColumns,"nTh"),[]),I=[],F=[],L=[],R=g.scrollHeight>g.clientHeight;n.scrollBarVis!==R&&n.scrollBarVis!==N?(n.scrollBarVis=R,O(n)):(n.scrollBarVis=R,D.children("thead, tfoot").remove(),C&&(R=C.clone().prependTo(D),i=C.find("tr"),a=R.find("tr"),R.find("[id]").removeAttr("id")),R=y.clone().prependTo(D),y=y.find("tr"),e=R.find("tr"),R.find("th, td").removeAttr("tabindex"),R.find("[id]").removeAttr("id"),s||(m.width="100%",f[0].style.width="100%"),P.each(Ct(n,R),function(t,e){r=rt(n,t),e.style.width=n.aoColumns[r].sWidth}),C&&k(function(t){t.style.width=""},a),f=D.outerWidth(),""===s?(w.width="100%",x&&(D.find("tbody").height()>g.offsetHeight||"scroll"==b.css("overflow-y"))&&(w.width=M(D.outerWidth()-l)),f=D.outerWidth()):""!==u&&(w.width=M(u),f=D.outerWidth()),k(t,e),k(function(t){var e=j.getComputedStyle?j.getComputedStyle(t).width:M(P(t).width());F.push(t.innerHTML),A.push(e)},e),k(function(t,e){t.style.width=A[e]},y),P(e).css("height",0),C&&(k(t,a),k(function(t){L.push(t.innerHTML),I.push(M(P(t).css("width")))},a),k(function(t,e){t.style.width=I[e]},i),P(a).height(0)),k(function(t,e){t.innerHTML='
'+F[e]+"
",t.childNodes[0].style.height="0",t.childNodes[0].style.overflow="hidden",t.style.width=A[e]},e),C&&k(function(t,e){t.innerHTML='
'+L[e]+"
",t.childNodes[0].style.height="0",t.childNodes[0].style.overflow="hidden",t.style.width=I[e]},a),Math.round(D.outerWidth())g.offsetHeight||"scroll"==b.css("overflow-y")?f+l:f,x&&(g.scrollHeight>g.offsetHeight||"scroll"==b.css("overflow-y"))&&(w.width=M(o-l)),""!==s&&""===u||W(n,1,"Possible column misalignment",6)):o="100%",m.width=M(o),d.width=M(o),C&&(n.nScrollFoot.style.width=M(o)),c||x&&(m.height=M(_.offsetHeight+l)),R=D.outerWidth(),h[0].style.width=M(R),p.width=M(R),y=D.height()>g.clientHeight||"scroll"==b.css("overflow-y"),p[i="padding"+(T.bScrollbarLeft?"Left":"Right")]=y?l+"px":"0px",C&&(v[0].style.width=M(R),S[0].style.width=M(R),S[0].style[i]=y?l+"px":"0px"),D.children("colgroup").insertBefore(D.children("thead")),b.trigger("scroll"),!n.bSorted&&!n.bFiltered||n._drawHold||(g.scrollTop=0))}function k(t,e,n){for(var a,r,o=0,i=0,l=e.length;i/g;function ee(t){var e,n,a=t.nTable,r=t.aoColumns,o=t.oScroll,i=o.sY,l=o.sX,o=o.sXInner,s=r.length,u=it(t,"bVisible"),c=P("th",t.nTHead),f=a.getAttribute("width"),d=a.parentNode,h=!1,p=t.oBrowser,g=p.bScrollOversize,b=a.style.width;for(b&&-1!==b.indexOf("%")&&(f=b),D=0;D").appendTo(b.find("tbody")));for(b.find("thead, tfoot").remove(),b.append(P(t.nTHead).clone()).append(P(t.nTFoot).clone()),b.find("tfoot th, tfoot td").css("width",""),c=Ct(t,b.find("thead")[0]),D=0;D").css({width:e.sWidthOrig,margin:0,padding:0,border:0,height:1}));if(t.aoData.length)for(D=0;D").css(l||i?{position:"absolute",top:0,left:0,height:1,right:0,overflow:"hidden"}:{}).append(b).appendTo(d),y=(l&&o?b.width(o):l?(b.css("width","auto"),b.removeAttr("width"),b.width()").css("width",M(t)).appendTo(e||y.body))[0].offsetWidth,t.remove(),e):0}function re(t,e){var n,a=oe(t,e);return a<0?null:(n=t.aoData[a]).nTr?n.anCells[e]:P("").html(S(t,a,e,"display"))[0]}function oe(t,e){for(var n,a=-1,r=-1,o=0,i=t.aoData.length;oa&&(a=n.length,r=o);return r}function M(t){return null===t?"0px":"number"==typeof t?t<0?"0px":t+"px":t.match(/\d$/)?t+"px":t}function I(t){function e(t){t.length&&!Array.isArray(t[0])?h.push(t):P.merge(h,t)}var n,a,r,o,i,l,s,u=[],c=t.aoColumns,f=t.aaSortingFixed,d=P.isPlainObject(f),h=[];for(Array.isArray(f)&&e(f),d&&f.pre&&e(f.pre),e(t.aaSorting),d&&f.post&&e(f.post),n=0;n/g,""),u=i.nTh;u.removeAttribute("aria-sort"),i=i.bSortable?s+("asc"===(0=o.length?[0,e[1]]:e)})),t.search!==N&&P.extend(n.oPreviousSearch,Bt(t.search)),t.columns){for(a=0,r=t.columns.length;a").addClass(e),P("td",n).addClass(e).html(t)[0].colSpan=T(o),l.push(n[0]))}var l=[];i(e,n),t._details&&t._details.detach(),t._details=P(l),t._detailsShow&&t._details.insertAfter(t.nTr)}function xe(t,e){var n=t.context;if(n.length&&t.length){var a=n[0].aoData[t[0]];if(a._details){(a._detailsShow=e)?(a._details.insertAfter(a.nTr),P(a.nTr).addClass("dt-hasChild")):(a._details.detach(),P(a.nTr).removeClass("dt-hasChild")),R(n[0],null,"childRow",[e,t.row(t[0])]);var s=n[0],r=new B(s),a=".dt.DT_details",e="draw"+a,t="column-sizing"+a,a="destroy"+a,u=s.aoData;if(r.off(e+" "+t+" "+a),H(u,"_details").length>0){r.on(e,function(t,e){if(s!==e)return;r.rows({page:"current"}).eq(0).each(function(t){var e=u[t];if(e._detailsShow)e._details.insertAfter(e.nTr)})});r.on(t,function(t,e,n,a){if(s!==e)return;var r,o=T(e);for(var i=0,l=u.length;it?new B(e[t],this[t]):null},filter:function(t){var e=[];if(o.filter)e=o.filter.call(this,t,this);else for(var n=0,a=this.length;n").appendTo(t);p(u,n)}else{switch(g=null,b=n,a=c.iTabIndex,n){case"ellipsis":t.append('');break;case"first":g=S.sFirst,0===d&&(a=-1,b+=" "+o);break;case"previous":g=S.sPrevious,0===d&&(a=-1,b+=" "+o);break;case"next":g=S.sNext,0!==h&&d!==h-1||(a=-1,b+=" "+o);break;case"last":g=S.sLast,0!==h&&d!==h-1||(a=-1,b+=" "+o);break;default:g=c.fnFormatNumber(n+1),b=d===n?m.sPageButtonActive:""}null!==g&&(u=c.oInit.pagingTag||"a",r=-1!==b.indexOf(o),me(P("<"+u+">",{class:m.sPageButton+" "+b,"aria-controls":c.sTableId,"aria-disabled":r?"true":null,"aria-label":v[n],"aria-role":"link","aria-current":b===m.sPageButtonActive?"page":null,"data-dt-idx":n,tabindex:a,id:0===f&&"string"==typeof n?c.sTableId+"_"+n:null}).html(g).appendTo(t),{action:n},i))}}var g,b,n,m=c.oClasses,S=c.oLanguage.oPaginate,v=c.oLanguage.oAria.paginate||{};try{n=P(t).find(y.activeElement).data("dt-idx")}catch(t){}p(P(t).empty(),e),n!==N&&P(t).find("[data-dt-idx="+n+"]").trigger("focus")}}}),P.extend(w.ext.type.detect,[function(t,e){e=e.oLanguage.sDecimal;return l(t,e)?"num"+e:null},function(t,e){var n;return(!t||t instanceof Date||X.test(t))&&(null!==(n=Date.parse(t))&&!isNaN(n)||h(t))?"date":null},function(t,e){e=e.oLanguage.sDecimal;return l(t,e,!0)?"num-fmt"+e:null},function(t,e){e=e.oLanguage.sDecimal;return a(t,e)?"html-num"+e:null},function(t,e){e=e.oLanguage.sDecimal;return a(t,e,!0)?"html-num-fmt"+e:null},function(t,e){return h(t)||"string"==typeof t&&-1!==t.indexOf("<")?"html":null}]),P.extend(w.ext.type.search,{html:function(t){return h(t)?t:"string"==typeof t?t.replace(U," ").replace(V,""):""},string:function(t){return!h(t)&&"string"==typeof t?t.replace(U," "):t}});function ke(t,e,n,a){var r;return 0===t||t&&"-"!==t?"number"==(r=typeof t)||"bigint"==r?t:+(t=(t=e?G(t,e):t).replace&&(n&&(t=t.replace(n,"")),a)?t.replace(a,""):t):-1/0}function Me(n){P.each({num:function(t){return ke(t,n)},"num-fmt":function(t){return ke(t,n,q)},"html-num":function(t){return ke(t,n,V)},"html-num-fmt":function(t){return ke(t,n,V,q)}},function(t,e){p.type.order[t+n+"-pre"]=e,t.match(/^html\-/)&&(p.type.search[t+n]=p.type.search.html)})}P.extend(p.type.order,{"date-pre":function(t){t=Date.parse(t);return isNaN(t)?-1/0:t},"html-pre":function(t){return h(t)?"":t.replace?t.replace(/<.*?>/g,"").toLowerCase():t+""},"string-pre":function(t){return h(t)?"":"string"==typeof t?t.toLowerCase():t.toString?t.toString():""},"string-asc":function(t,e){return t").addClass(l.sSortJUIWrapper).append(o.contents()).append(P("").addClass(l.sSortIcon+" "+i.sSortingClassJUI)).appendTo(o),P(r.nTable).on("order.dt.DT",function(t,e,n,a){r===e&&(e=i.idx,o.removeClass(l.sSortAsc+" "+l.sSortDesc).addClass("asc"==a[e]?l.sSortAsc:"desc"==a[e]?l.sSortDesc:i.sSortingClass),o.find("span."+l.sSortIcon).removeClass(l.sSortJUIAsc+" "+l.sSortJUIDesc+" "+l.sSortJUI+" "+l.sSortJUIAscAllowed+" "+l.sSortJUIDescAllowed).addClass("asc"==a[e]?l.sSortJUIAsc:"desc"==a[e]?l.sSortJUIDesc:i.sSortingClassJUI))})}}});function We(t){return"string"==typeof(t=Array.isArray(t)?t.join(","):t)?t.replace(/&/g,"&").replace(//g,">").replace(/"/g,"""):t}function Ee(t,e,n,a,r){return j.moment?t[e](r):j.luxon?t[n](r):a?t[a](r):t}var Be=!1;function Ue(t,e,n){var a;if(j.moment){if(!(a=j.moment.utc(t,e,n,!0)).isValid())return null}else if(j.luxon){if(!(a=e&&"string"==typeof t?j.luxon.DateTime.fromFormat(t,e):j.luxon.DateTime.fromISO(t)).isValid)return null;a.setLocale(n)}else e?(Be||alert("DataTables warning: Formatted date without Moment.js or Luxon - https://datatables.net/tn/17"),Be=!0):a=new Date(t);return a}function Ve(s){return function(a,r,o,i){0===arguments.length?(o="en",a=r=null):1===arguments.length?(o="en",r=a,a=null):2===arguments.length&&(o=r,r=a,a=null);var l="datetime-"+r;return w.ext.type.order[l]||(w.ext.type.detect.unshift(function(t){return t===l&&l}),w.ext.type.order[l+"-asc"]=function(t,e){t=t.valueOf(),e=e.valueOf();return t===e?0:t").addClass(errClass); + errorSpan.text(err.message); + $el.after(errorSpan); + } + } else if (display === "block") { + // If block, add an error just after the el, set visibility:none on the + // el, and position the error to be on top of the el. + // Mark it with a unique ID and CSS class so we can remove it later. + $el.css("visibility", "hidden"); + if (err.message !== "") { + var errorDiv = $("
").addClass(errClass).css("position", "absolute") + .css("top", el.offsetTop) + .css("left", el.offsetLeft) + // setting width can push out the page size, forcing otherwise + // unnecessary scrollbars to appear and making it impossible for + // the element to shrink; so use max-width instead + .css("maxWidth", el.offsetWidth) + .css("height", el.offsetHeight); + errorDiv.text(err.message); + $el.after(errorDiv); + + // Really dumb way to keep the size/position of the error in sync with + // the parent element as the window is resized or whatever. + var intId = setInterval(function() { + if (!errorDiv[0].parentElement) { + clearInterval(intId); + return; + } + errorDiv + .css("top", el.offsetTop) + .css("left", el.offsetLeft) + .css("maxWidth", el.offsetWidth) + .css("height", el.offsetHeight); + }, 500); + } + } + }, + clearError: function(el) { + var $el = $(el); + var display = $el.data("restore-display-mode"); + $el.data("restore-display-mode", null); + + if (display === "inline" || display === "inline-block") { + if (display) + $el.css("display", display); + $(el.nextSibling).filter(".htmlwidgets-error").remove(); + } else if (display === "block"){ + $el.css("visibility", "inherit"); + $(el.nextSibling).filter(".htmlwidgets-error").remove(); + } + }, + sizing: {} + }; + + // Called by widget bindings to register a new type of widget. The definition + // object can contain the following properties: + // - name (required) - A string indicating the binding name, which will be + // used by default as the CSS classname to look for. + // - initialize (optional) - A function(el) that will be called once per + // widget element; if a value is returned, it will be passed as the third + // value to renderValue. + // - renderValue (required) - A function(el, data, initValue) that will be + // called with data. Static contexts will cause this to be called once per + // element; Shiny apps will cause this to be called multiple times per + // element, as the data changes. + window.HTMLWidgets.widget = function(definition) { + if (!definition.name) { + throw new Error("Widget must have a name"); + } + if (!definition.type) { + throw new Error("Widget must have a type"); + } + // Currently we only support output widgets + if (definition.type !== "output") { + throw new Error("Unrecognized widget type '" + definition.type + "'"); + } + // TODO: Verify that .name is a valid CSS classname + + // Support new-style instance-bound definitions. Old-style class-bound + // definitions have one widget "object" per widget per type/class of + // widget; the renderValue and resize methods on such widget objects + // take el and instance arguments, because the widget object can't + // store them. New-style instance-bound definitions have one widget + // object per widget instance; the definition that's passed in doesn't + // provide renderValue or resize methods at all, just the single method + // factory(el, width, height) + // which returns an object that has renderValue(x) and resize(w, h). + // This enables a far more natural programming style for the widget + // author, who can store per-instance state using either OO-style + // instance fields or functional-style closure variables (I guess this + // is in contrast to what can only be called C-style pseudo-OO which is + // what we required before). + if (definition.factory) { + definition = createLegacyDefinitionAdapter(definition); + } + + if (!definition.renderValue) { + throw new Error("Widget must have a renderValue function"); + } + + // For static rendering (non-Shiny), use a simple widget registration + // scheme. We also use this scheme for Shiny apps/documents that also + // contain static widgets. + window.HTMLWidgets.widgets = window.HTMLWidgets.widgets || []; + // Merge defaults into the definition; don't mutate the original definition. + var staticBinding = extend({}, defaults, definition); + overrideMethod(staticBinding, "find", function(superfunc) { + return function(scope) { + var results = superfunc(scope); + // Filter out Shiny outputs, we only want the static kind + return filterByClass(results, "html-widget-output", false); + }; + }); + window.HTMLWidgets.widgets.push(staticBinding); + + if (shinyMode) { + // Shiny is running. Register the definition with an output binding. + // The definition itself will not be the output binding, instead + // we will make an output binding object that delegates to the + // definition. This is because we foolishly used the same method + // name (renderValue) for htmlwidgets definition and Shiny bindings + // but they actually have quite different semantics (the Shiny + // bindings receive data that includes lots of metadata that it + // strips off before calling htmlwidgets renderValue). We can't + // just ignore the difference because in some widgets it's helpful + // to call this.renderValue() from inside of resize(), and if + // we're not delegating, then that call will go to the Shiny + // version instead of the htmlwidgets version. + + // Merge defaults with definition, without mutating either. + var bindingDef = extend({}, defaults, definition); + + // This object will be our actual Shiny binding. + var shinyBinding = new Shiny.OutputBinding(); + + // With a few exceptions, we'll want to simply use the bindingDef's + // version of methods if they are available, otherwise fall back to + // Shiny's defaults. NOTE: If Shiny's output bindings gain additional + // methods in the future, and we want them to be overrideable by + // HTMLWidget binding definitions, then we'll need to add them to this + // list. + delegateMethod(shinyBinding, bindingDef, "getId"); + delegateMethod(shinyBinding, bindingDef, "onValueChange"); + delegateMethod(shinyBinding, bindingDef, "onValueError"); + delegateMethod(shinyBinding, bindingDef, "renderError"); + delegateMethod(shinyBinding, bindingDef, "clearError"); + delegateMethod(shinyBinding, bindingDef, "showProgress"); + + // The find, renderValue, and resize are handled differently, because we + // want to actually decorate the behavior of the bindingDef methods. + + shinyBinding.find = function(scope) { + var results = bindingDef.find(scope); + + // Only return elements that are Shiny outputs, not static ones + var dynamicResults = results.filter(".html-widget-output"); + + // It's possible that whatever caused Shiny to think there might be + // new dynamic outputs, also caused there to be new static outputs. + // Since there might be lots of different htmlwidgets bindings, we + // schedule execution for later--no need to staticRender multiple + // times. + if (results.length !== dynamicResults.length) + scheduleStaticRender(); + + return dynamicResults; + }; + + // Wrap renderValue to handle initialization, which unfortunately isn't + // supported natively by Shiny at the time of this writing. + + shinyBinding.renderValue = function(el, data) { + Shiny.renderDependencies(data.deps); + // Resolve strings marked as javascript literals to objects + if (!(data.evals instanceof Array)) data.evals = [data.evals]; + for (var i = 0; data.evals && i < data.evals.length; i++) { + window.HTMLWidgets.evaluateStringMember(data.x, data.evals[i]); + } + if (!bindingDef.renderOnNullValue) { + if (data.x === null) { + el.style.visibility = "hidden"; + return; + } else { + el.style.visibility = "inherit"; + } + } + if (!elementData(el, "initialized")) { + initSizing(el); + + elementData(el, "initialized", true); + if (bindingDef.initialize) { + var rect = el.getBoundingClientRect(); + var result = bindingDef.initialize(el, rect.width, rect.height); + elementData(el, "init_result", result); + } + } + bindingDef.renderValue(el, data.x, elementData(el, "init_result")); + evalAndRun(data.jsHooks.render, elementData(el, "init_result"), [el, data.x]); + }; + + // Only override resize if bindingDef implements it + if (bindingDef.resize) { + shinyBinding.resize = function(el, width, height) { + // Shiny can call resize before initialize/renderValue have been + // called, which doesn't make sense for widgets. + if (elementData(el, "initialized")) { + bindingDef.resize(el, width, height, elementData(el, "init_result")); + } + }; + } + + Shiny.outputBindings.register(shinyBinding, bindingDef.name); + } + }; + + var scheduleStaticRenderTimerId = null; + function scheduleStaticRender() { + if (!scheduleStaticRenderTimerId) { + scheduleStaticRenderTimerId = setTimeout(function() { + scheduleStaticRenderTimerId = null; + window.HTMLWidgets.staticRender(); + }, 1); + } + } + + // Render static widgets after the document finishes loading + // Statically render all elements that are of this widget's class + window.HTMLWidgets.staticRender = function() { + var bindings = window.HTMLWidgets.widgets || []; + forEach(bindings, function(binding) { + var matches = binding.find(document.documentElement); + forEach(matches, function(el) { + var sizeObj = initSizing(el, binding); + + var getSize = function(el) { + if (sizeObj) { + return {w: sizeObj.getWidth(), h: sizeObj.getHeight()} + } else { + var rect = el.getBoundingClientRect(); + return {w: rect.width, h: rect.height} + } + }; + + if (hasClass(el, "html-widget-static-bound")) + return; + el.className = el.className + " html-widget-static-bound"; + + var initResult; + if (binding.initialize) { + var size = getSize(el); + initResult = binding.initialize(el, size.w, size.h); + elementData(el, "init_result", initResult); + } + + if (binding.resize) { + var lastSize = getSize(el); + var resizeHandler = function(e) { + var size = getSize(el); + if (size.w === 0 && size.h === 0) + return; + if (size.w === lastSize.w && size.h === lastSize.h) + return; + lastSize = size; + binding.resize(el, size.w, size.h, initResult); + }; + + on(window, "resize", resizeHandler); + + // This is needed for cases where we're running in a Shiny + // app, but the widget itself is not a Shiny output, but + // rather a simple static widget. One example of this is + // an rmarkdown document that has runtime:shiny and widget + // that isn't in a render function. Shiny only knows to + // call resize handlers for Shiny outputs, not for static + // widgets, so we do it ourselves. + if (window.jQuery) { + window.jQuery(document).on( + "shown.htmlwidgets shown.bs.tab.htmlwidgets shown.bs.collapse.htmlwidgets", + resizeHandler + ); + window.jQuery(document).on( + "hidden.htmlwidgets hidden.bs.tab.htmlwidgets hidden.bs.collapse.htmlwidgets", + resizeHandler + ); + } + + // This is needed for the specific case of ioslides, which + // flips slides between display:none and display:block. + // Ideally we would not have to have ioslide-specific code + // here, but rather have ioslides raise a generic event, + // but the rmarkdown package just went to CRAN so the + // window to getting that fixed may be long. + if (window.addEventListener) { + // It's OK to limit this to window.addEventListener + // browsers because ioslides itself only supports + // such browsers. + on(document, "slideenter", resizeHandler); + on(document, "slideleave", resizeHandler); + } + } + + var scriptData = document.querySelector("script[data-for='" + el.id + "'][type='application/json']"); + if (scriptData) { + var data = JSON.parse(scriptData.textContent || scriptData.text); + // Resolve strings marked as javascript literals to objects + if (!(data.evals instanceof Array)) data.evals = [data.evals]; + for (var k = 0; data.evals && k < data.evals.length; k++) { + window.HTMLWidgets.evaluateStringMember(data.x, data.evals[k]); + } + binding.renderValue(el, data.x, initResult); + evalAndRun(data.jsHooks.render, initResult, [el, data.x]); + } + }); + }); + + invokePostRenderHandlers(); + } + + + function has_jQuery3() { + if (!window.jQuery) { + return false; + } + var $version = window.jQuery.fn.jquery; + var $major_version = parseInt($version.split(".")[0]); + return $major_version >= 3; + } + + /* + / Shiny 1.4 bumped jQuery from 1.x to 3.x which means jQuery's + / on-ready handler (i.e., $(fn)) is now asyncronous (i.e., it now + / really means $(setTimeout(fn)). + / https://jquery.com/upgrade-guide/3.0/#breaking-change-document-ready-handlers-are-now-asynchronous + / + / Since Shiny uses $() to schedule initShiny, shiny>=1.4 calls initShiny + / one tick later than it did before, which means staticRender() is + / called renderValue() earlier than (advanced) widget authors might be expecting. + / https://github.com/rstudio/shiny/issues/2630 + / + / For a concrete example, leaflet has some methods (e.g., updateBounds) + / which reference Shiny methods registered in initShiny (e.g., setInputValue). + / Since leaflet is privy to this life-cycle, it knows to use setTimeout() to + / delay execution of those methods (until Shiny methods are ready) + / https://github.com/rstudio/leaflet/blob/18ec981/javascript/src/index.js#L266-L268 + / + / Ideally widget authors wouldn't need to use this setTimeout() hack that + / leaflet uses to call Shiny methods on a staticRender(). In the long run, + / the logic initShiny should be broken up so that method registration happens + / right away, but binding happens later. + */ + function maybeStaticRenderLater() { + if (shinyMode && has_jQuery3()) { + window.jQuery(window.HTMLWidgets.staticRender); + } else { + window.HTMLWidgets.staticRender(); + } + } + + if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", function() { + document.removeEventListener("DOMContentLoaded", arguments.callee, false); + maybeStaticRenderLater(); + }, false); + } else if (document.attachEvent) { + document.attachEvent("onreadystatechange", function() { + if (document.readyState === "complete") { + document.detachEvent("onreadystatechange", arguments.callee); + maybeStaticRenderLater(); + } + }); + } + + + window.HTMLWidgets.getAttachmentUrl = function(depname, key) { + // If no key, default to the first item + if (typeof(key) === "undefined") + key = 1; + + var link = document.getElementById(depname + "-" + key + "-attachment"); + if (!link) { + throw new Error("Attachment " + depname + "/" + key + " not found in document"); + } + return link.getAttribute("href"); + }; + + window.HTMLWidgets.dataframeToD3 = function(df) { + var names = []; + var length; + for (var name in df) { + if (df.hasOwnProperty(name)) + names.push(name); + if (typeof(df[name]) !== "object" || typeof(df[name].length) === "undefined") { + throw new Error("All fields must be arrays"); + } else if (typeof(length) !== "undefined" && length !== df[name].length) { + throw new Error("All fields must be arrays of the same length"); + } + length = df[name].length; + } + var results = []; + var item; + for (var row = 0; row < length; row++) { + item = {}; + for (var col = 0; col < names.length; col++) { + item[names[col]] = df[names[col]][row]; + } + results.push(item); + } + return results; + }; + + window.HTMLWidgets.transposeArray2D = function(array) { + if (array.length === 0) return array; + var newArray = array[0].map(function(col, i) { + return array.map(function(row) { + return row[i] + }) + }); + return newArray; + }; + // Split value at splitChar, but allow splitChar to be escaped + // using escapeChar. Any other characters escaped by escapeChar + // will be included as usual (including escapeChar itself). + function splitWithEscape(value, splitChar, escapeChar) { + var results = []; + var escapeMode = false; + var currentResult = ""; + for (var pos = 0; pos < value.length; pos++) { + if (!escapeMode) { + if (value[pos] === splitChar) { + results.push(currentResult); + currentResult = ""; + } else if (value[pos] === escapeChar) { + escapeMode = true; + } else { + currentResult += value[pos]; + } + } else { + currentResult += value[pos]; + escapeMode = false; + } + } + if (currentResult !== "") { + results.push(currentResult); + } + return results; + } + // Function authored by Yihui/JJ Allaire + window.HTMLWidgets.evaluateStringMember = function(o, member) { + var parts = splitWithEscape(member, '.', '\\'); + for (var i = 0, l = parts.length; i < l; i++) { + var part = parts[i]; + // part may be a character or 'numeric' member name + if (o !== null && typeof o === "object" && part in o) { + if (i == (l - 1)) { // if we are at the end of the line then evalulate + if (typeof o[part] === "string") + o[part] = tryEval(o[part]); + } else { // otherwise continue to next embedded object + o = o[part]; + } + } + } + }; + + // Retrieve the HTMLWidget instance (i.e. the return value of an + // HTMLWidget binding's initialize() or factory() function) + // associated with an element, or null if none. + window.HTMLWidgets.getInstance = function(el) { + return elementData(el, "init_result"); + }; + + // Finds the first element in the scope that matches the selector, + // and returns the HTMLWidget instance (i.e. the return value of + // an HTMLWidget binding's initialize() or factory() function) + // associated with that element, if any. If no element matches the + // selector, or the first matching element has no HTMLWidget + // instance associated with it, then null is returned. + // + // The scope argument is optional, and defaults to window.document. + window.HTMLWidgets.find = function(scope, selector) { + if (arguments.length == 1) { + selector = scope; + scope = document; + } + + var el = scope.querySelector(selector); + if (el === null) { + return null; + } else { + return window.HTMLWidgets.getInstance(el); + } + }; + + // Finds all elements in the scope that match the selector, and + // returns the HTMLWidget instances (i.e. the return values of + // an HTMLWidget binding's initialize() or factory() function) + // associated with the elements, in an array. If elements that + // match the selector don't have an associated HTMLWidget + // instance, the returned array will contain nulls. + // + // The scope argument is optional, and defaults to window.document. + window.HTMLWidgets.findAll = function(scope, selector) { + if (arguments.length == 1) { + selector = scope; + scope = document; + } + + var nodes = scope.querySelectorAll(selector); + var results = []; + for (var i = 0; i < nodes.length; i++) { + results.push(window.HTMLWidgets.getInstance(nodes[i])); + } + return results; + }; + + var postRenderHandlers = []; + function invokePostRenderHandlers() { + while (postRenderHandlers.length) { + var handler = postRenderHandlers.shift(); + if (handler) { + handler(); + } + } + } + + // Register the given callback function to be invoked after the + // next time static widgets are rendered. + window.HTMLWidgets.addPostRenderHandler = function(callback) { + postRenderHandlers.push(callback); + }; + + // Takes a new-style instance-bound definition, and returns an + // old-style class-bound definition. This saves us from having + // to rewrite all the logic in this file to accomodate both + // types of definitions. + function createLegacyDefinitionAdapter(defn) { + var result = { + name: defn.name, + type: defn.type, + initialize: function(el, width, height) { + return defn.factory(el, width, height); + }, + renderValue: function(el, x, instance) { + return instance.renderValue(x); + }, + resize: function(el, width, height, instance) { + return instance.resize(width, height); + } + }; + + if (defn.find) + result.find = defn.find; + if (defn.renderError) + result.renderError = defn.renderError; + if (defn.clearError) + result.clearError = defn.clearError; + + return result; + } +})(); diff --git a/public/site_libs/jquery-3.6.0/jquery-3.6.0.js b/public/site_libs/jquery-3.6.0/jquery-3.6.0.js new file mode 100644 index 00000000..fc6c299b --- /dev/null +++ b/public/site_libs/jquery-3.6.0/jquery-3.6.0.js @@ -0,0 +1,10881 @@ +/*! + * jQuery JavaScript Library v3.6.0 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright OpenJS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2021-03-02T17:08Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var flat = arr.flat ? function( array ) { + return arr.flat.call( array ); +} : function( array ) { + return arr.concat.apply( [], array ); +}; + + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + +var isFunction = function isFunction( obj ) { + + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 + // Plus for old WebKit, typeof returns "function" for HTML collections + // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756) + return typeof obj === "function" && typeof obj.nodeType !== "number" && + typeof obj.item !== "function"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + +var document = window.document; + + + + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + function DOMEval( code, node, doc ) { + doc = doc || document; + + var i, val, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); + } + } + } + doc.head.appendChild( script ).parentNode.removeChild( script ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.6.0", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + even: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return ( i + 1 ) % 2; + } ) ); + }, + + odd: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return i % 2; + } ) ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a provided context; falls back to the global one + // if not specified. + globalEval: function( code, options, doc ) { + DOMEval( code, { nonce: options && options.nonce }, doc ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return flat( ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), + function( _i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); + } ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); + + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.6 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2021-02-16 + */ +( function( window ) { +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ( {} ).hasOwnProperty, + arr = [], + pop = arr.pop, + pushNative = arr.push, + push = arr.push, + slice = arr.slice, + + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[ i ] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + + "ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram + identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + + // "Attribute values must be CSS identifiers [capture 5] + // or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + + whitespace + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rhtml = /HTML$/i, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; + + return nonHex ? + + // Strip the backslash prefix from a non-hex escape sequence + nonHex : + + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + ( arr = slice.call( preferredDoc.childNodes ) ), + preferredDoc.childNodes + ); + + // Support: Android<4.0 + // Detect silently failing push.apply + // eslint-disable-next-line no-unused-expressions + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + pushNative.apply( target, slice.call( els ) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + + // Can't trust NodeList.length + while ( ( target[ j++ ] = els[ i++ ] ) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + setDocument( context ); + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { + + // ID selector + if ( ( m = match[ 1 ] ) ) { + + // Document context + if ( nodeType === 9 ) { + if ( ( elem = context.getElementById( m ) ) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && ( elem = newContext.getElementById( m ) ) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[ 2 ] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !nonnativeSelectorCache[ selector + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && + + // Support: IE 8 only + // Exclude object elements + ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { + + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // The technique has to be used as well when a leading combinator is used + // as such selectors are not recognized by querySelectorAll. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && + ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + if ( newContext !== context || !support.scope ) { + + // Capture the context ID, setting it first if necessary + if ( ( nid = context.getAttribute( "id" ) ) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", ( nid = expando ) ); + } + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + + toSelector( groups[ i ] ); + } + newSelector = groups.join( "," ); + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return ( cache[ key + " " ] = value ); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement( "fieldset" ); + + try { + return !!fn( el ); + } catch ( e ) { + return false; + } finally { + + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split( "|" ), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[ i ] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( ( cur = cur.nextSibling ) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return ( name === "input" || name === "button" ) && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction( function( argument ) { + argument = +argument; + return markFunction( function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ ( j = matchIndexes[ i ] ) ] ) { + seed[ j ] = !( matches[ j ] = seed[ j ] ); + } + } + } ); + } ); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + var namespace = elem && elem.namespaceURI, + docElem = elem && ( elem.ownerDocument || elem ).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9 - 11+, Edge 12 - 18+ + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( preferredDoc != document && + ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, + // Safari 4 - 5 only, Opera <=11.6 - 12.x only + // IE/Edge & older browsers don't support the :scope pseudo-class. + // Support: Safari 6.0 only + // Safari 6.0 supports :scope but it's an alias of :root there. + support.scope = assert( function( el ) { + docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); + return typeof el.querySelectorAll !== "undefined" && + !el.querySelectorAll( ":scope fieldset div" ).length; + } ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert( function( el ) { + el.className = "i"; + return !el.getAttribute( "className" ); + } ); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert( function( el ) { + el.appendChild( document.createComment( "" ) ); + return !el.getElementsByTagName( "*" ).length; + } ); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert( function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + } ); + + // ID filter and find + if ( support.getById ) { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute( "id" ) === attrId; + }; + }; + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode( "id" ); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( ( elem = elems[ i++ ] ) ) { + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find[ "TAG" ] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert( function( el ) { + + var input; + + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll( "[selected]" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push( "~=" ); + } + + // Support: IE 11+, Edge 15 - 18+ + // IE 11/Edge don't find elements on a `[name='']` query in some cases. + // Adding a temporary attribute to the document before the selection works + // around the issue. + // Interestingly, IE 10 & older don't seem to have the issue. + input = document.createElement( "input" ); + input.setAttribute( "name", "" ); + el.appendChild( input ); + if ( !el.querySelectorAll( "[name='']" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + + whitespace + "*(?:''|\"\")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll( ":checked" ).length ) { + rbuggyQSA.push( ":checked" ); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push( ".#.+[+~]" ); + } + + // Support: Firefox <=3.6 - 5 only + // Old Firefox doesn't throw on a badly-escaped identifier. + el.querySelectorAll( "\\\f" ); + rbuggyQSA.push( "[\\r\\n\\f]" ); + } ); + + assert( function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement( "input" ); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll( "[name=d]" ).length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: Opera 10 - 11 only + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll( "*,:x" ); + rbuggyQSA.push( ",.*:" ); + } ); + } + + if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector ) ) ) ) { + + assert( function( el ) { + + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + } ); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + ) ); + } : + function( a, b ) { + if ( b ) { + while ( ( b = b.parentNode ) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { + + // Choose the first element that is related to our preferred document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( a == document || a.ownerDocument == preferredDoc && + contains( preferredDoc, a ) ) { + return -1; + } + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( b == document || b.ownerDocument == preferredDoc && + contains( preferredDoc, b ) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + return a == document ? -1 : + b == document ? 1 : + /* eslint-enable eqeqeq */ + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( ( cur = cur.parentNode ) ) { + ap.unshift( cur ); + } + cur = b; + while ( ( cur = cur.parentNode ) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[ i ] === bp[ i ] ) { + i++; + } + + return i ? + + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[ i ], bp[ i ] ) : + + // Otherwise nodes in our document sort first + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + ap[ i ] == preferredDoc ? -1 : + bp[ i ] == preferredDoc ? 1 : + /* eslint-enable eqeqeq */ + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + setDocument( elem ); + + if ( support.matchesSelector && documentIsHTML && + !nonnativeSelectorCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch ( e ) { + nonnativeSelectorCache( expr, true ); + } + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( context.ownerDocument || context ) != document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( elem.ownerDocument || elem ) != document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + + // If no nodeType, this is expected to be an array + while ( ( node = elem[ i++ ] ) ) { + + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[ 1 ] = match[ 1 ].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[ 3 ] = ( match[ 3 ] || match[ 4 ] || + match[ 5 ] || "" ).replace( runescape, funescape ); + + if ( match[ 2 ] === "~=" ) { + match[ 3 ] = " " + match[ 3 ] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[ 1 ] = match[ 1 ].toLowerCase(); + + if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { + + // nth-* requires argument + if ( !match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[ 4 ] = +( match[ 4 ] ? + match[ 5 ] + ( match[ 6 ] || 1 ) : + 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); + match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); + + // other types prohibit arguments + } else if ( match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[ 6 ] && match[ 2 ]; + + if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[ 3 ] ) { + match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + + // Get excess from tokenize (recursively) + ( excess = tokenize( unquoted, true ) ) && + + // advance to the next closing parenthesis + ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { + + // excess is a negative index + match[ 0 ] = match[ 0 ].slice( 0, excess ); + match[ 2 ] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { + return true; + } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + ( pattern = new RegExp( "(^|" + whitespace + + ")" + className + "(" + whitespace + "|$)" ) ) && classCache( + className, function( elem ) { + return pattern.test( + typeof elem.className === "string" && elem.className || + typeof elem.getAttribute !== "undefined" && + elem.getAttribute( "class" ) || + "" + ); + } ); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + /* eslint-disable max-len */ + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + /* eslint-enable max-len */ + + }; + }, + + "CHILD": function( type, what, _argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, _context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( ( node = node[ dir ] ) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( ( node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + + // Use previously-cached element index if available + if ( useCache ) { + + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + + // Use the same loop as above to seek `elem` from the start + while ( ( node = ++nodeIndex && node && node[ dir ] || + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || + ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction( function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[ i ] ); + seed[ idx ] = !( matches[ idx ] = matched[ i ] ); + } + } ) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + + // Potentially complex pseudos + "not": markFunction( function( selector ) { + + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction( function( seed, matches, _context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( ( elem = unmatched[ i ] ) ) { + seed[ i ] = !( matches[ i ] = elem ); + } + } + } ) : + function( elem, _context, xml ) { + input[ 0 ] = elem; + matcher( input, null, xml, results ); + + // Don't keep the element (issue #299) + input[ 0 ] = null; + return !results.pop(); + }; + } ), + + "has": markFunction( function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + } ), + + "contains": markFunction( function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; + }; + } ), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + + // lang value must be a valid identifier + if ( !ridentifier.test( lang || "" ) ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( ( elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); + return false; + }; + } ), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && + ( !document.hasFocus || document.hasFocus() ) && + !!( elem.type || elem.href || ~elem.tabIndex ); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return ( nodeName === "input" && !!elem.checked ) || + ( nodeName === "option" && !!elem.selected ); + }, + + "selected": function( elem ) { + + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + // eslint-disable-next-line no-unused-expressions + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos[ "empty" ]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( ( attr = elem.getAttribute( "type" ) ) == null || + attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo( function() { + return [ 0 ]; + } ), + + "last": createPositionalPseudo( function( _matchIndexes, length ) { + return [ length - 1 ]; + } ), + + "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + } ), + + "even": createPositionalPseudo( function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "odd": createPositionalPseudo( function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? + argument + length : + argument > length ? + length : + argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ) + } +}; + +Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || ( match = rcomma.exec( soFar ) ) ) { + if ( match ) { + + // Don't consume trailing commas as valid + soFar = soFar.slice( match[ 0 ].length ) || soFar; + } + groups.push( ( tokens = [] ) ); + } + + matched = false; + + // Combinators + if ( ( match = rcombinators.exec( soFar ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + + // Cast descendant combinators to space + type: match[ 0 ].replace( rtrim, " " ) + } ); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || + ( match = preFilters[ type ]( match ) ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + type: type, + matches: match + } ); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[ i ].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || ( elem[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || + ( outerCache[ elem.uniqueID ] = {} ); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( ( oldCache = uniqueCache[ key ] ) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return ( newCache[ 2 ] = oldCache[ 2 ] ); + } else { + + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[ i ]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[ 0 ]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[ i ], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( ( elem = unmatched[ i ] ) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction( function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( + selector || "*", + context.nodeType ? [ context ] : context, + [] + ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( ( elem = temp[ i ] ) ) { + matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) ) { + + // Restore matcherIn since elem is not yet a final match + temp.push( ( matcherIn[ i ] = elem ) ); + } + } + postFinder( null, ( matcherOut = [] ), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) && + ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { + + seed[ temp ] = !( results[ temp ] = elem ); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + } ); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[ 0 ].type ], + implicitRelative = leadingRelative || Expr.relative[ " " ], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + ( checkContext = context ).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[ j ].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens + .slice( 0, i - 1 ) + .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), + + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), + len = elems.length; + + if ( outermost ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + outermostContext = context == document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( !context && elem.ownerDocument != document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( ( matcher = elementMatchers[ j++ ] ) ) { + if ( matcher( elem, context || document, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + + // They will have gone through all possible matchers + if ( ( elem = !matcher && elem ) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( ( matcher = setMatchers[ j++ ] ) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !( unmatched[ i ] || setMatched[ i ] ) ) { + setMatched[ i ] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[ i ] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( + selector, + matcherFromGroupMatchers( elementMatchers, setMatchers ) + ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( ( selector = compiled.selector || selector ) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[ 0 ] = match[ 0 ].slice( 0 ); + if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { + + context = ( Expr.find[ "ID" ]( token.matches[ 0 ] + .replace( runescape, funescape ), context ) || [] )[ 0 ]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[ i ]; + + // Abort if we hit a combinator + if ( Expr.relative[ ( type = token.type ) ] ) { + break; + } + if ( ( find = Expr.find[ type ] ) ) { + + // Search, expanding context for leading sibling combinators + if ( ( seed = find( + token.matches[ 0 ].replace( runescape, funescape ), + rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || + context + ) ) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert( function( el ) { + + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; +} ); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert( function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute( "href" ) === "#"; +} ) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + } ); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert( function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +} ) ) { + addHandle( "value", function( elem, _name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + } ); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert( function( el ) { + return el.getAttribute( "disabled" ) == null; +} ) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; + } + } ); +} + +return Sizzle; + +} )( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +} +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, _i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, _i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, _i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( elem.contentDocument != null && + + // Support: IE 11+ + // elements with no `data` attribute has an object + // `contentDocument` with a `null` prototype. + getProto( elem.contentDocument ) ) { + + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && toType( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( _i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the primary Deferred + primary = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + primary.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( primary.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return primary.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject ); + } + + return primary.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, _key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( _all, letter ) { + return letter.toUpperCase(); +} + +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var documentElement = document.documentElement; + + + + var isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ); + }, + composed = { composed: true }; + + // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only + // Check attachment across shadow DOM boundaries when possible (gh-3504) + // Support: iOS 10.0-10.2 only + // Early iOS 10 versions support `attachShadow` but not `getRootNode`, + // leading to errors. We need to check for `getRootNode`. + if ( documentElement.getRootNode ) { + isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ) || + elem.getRootNode( composed ) === elem.ownerDocument; + }; + } +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + isAttached( elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, scale, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = elem.nodeType && + ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while ( maxIterations-- ) { + + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); + +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); + + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // Support: IE <=9 only + // IE <=9 replaces "; + support.option = !!div.lastChild; +} )(); + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] +}; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: IE <=9 only +if ( !support.option ) { + wrapMap.optgroup = wrapMap.option = [ 1, "" ]; +} + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, attached, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + attached = isAttached( elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 - 11+ +// focus() and blur() are asynchronous, except when they are no-op. +// So expect focus to be synchronous when the element is already active, +// and blur to be synchronous when the element is not already active. +// (focus and blur are always synchronous in other supported browsers, +// this just defines when we can count on it). +function expectSync( elem, type ) { + return ( elem === safeActiveElement() ) === ( type === "focus" ); +} + +// Support: IE <=9 only +// Accessing document.activeElement can throw unexpectedly +// https://bugs.jquery.com/ticket/13393 +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Only attach events to objects that accept data + if ( !acceptData( elem ) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = Object.create( null ); + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( nativeEvent ), + + handlers = ( + dataPriv.get( this, "events" ) || Object.create( null ) + )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", returnTrue ); + } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; + }, + + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack + _default: function( event ) { + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, expectSync ) { + + // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add + if ( !expectSync ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + return; + } + + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var notAsync, result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + // Saved data should be false in such cases, but might be a leftover capture object + // from an async native handler (gh-4350) + if ( !saved.length ) { + + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); + + // Trigger the native event and capture its result + // Support: IE <=9 - 11+ + // focus() and blur() are asynchronous + notAsync = expectSync( this, type ); + this[ type ](); + result = dataPriv.get( this, type ); + if ( saved !== result || notAsync ) { + dataPriv.set( this, type, false ); + } else { + result = {}; + } + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + + // Support: Chrome 86+ + // In Chrome, if an element having a focusout handler is blurred by + // clicking outside of it, it invokes the handler synchronously. If + // that handler calls `.remove()` on the element, the data is cleared, + // leaving `result` undefined. We need to guard against this. + return result && result.value; + } + + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering the + // native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } + + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved.length ) { + + // ...and capture the result + dataPriv.set( this, type, { + value: jQuery.event.trigger( + + // Support: IE <=9 - 11+ + // Extend with the prototype to reset the above stopImmediatePropagation() + jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), + saved.slice( 1 ), + this + ) + } ); + + // Abort handling of the native event + event.stopImmediatePropagation(); + } + } + } ); +} + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + code: true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + which: true +}, jQuery.event.addProp ); + +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, expectSync ); + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + // Suppress native focus or blur as it's already being fired + // in leverageNative. + _default: function() { + return true; + }, + + delegateType: delegateType + }; +} ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.get( src ); + events = pdataOld.events; + + if ( events ) { + dataPriv.remove( dest, "handle events" ); + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = flat( args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + }, doc ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html; + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var swap = function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableTrDimensionsVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + }, + + // Support: IE 9 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Behavior in IE 9 is more subtle than in newer versions & it passes + // some versions of this test; make sure not to make it pass there! + // + // Support: Firefox 70+ + // Only Firefox includes border widths + // in computed dimensions. (gh-4529) + reliableTrDimensions: function() { + var table, tr, trChild, trStyle; + if ( reliableTrDimensionsVal == null ) { + table = document.createElement( "table" ); + tr = document.createElement( "tr" ); + trChild = document.createElement( "div" ); + + table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; + tr.style.cssText = "border:1px solid"; + + // Support: Chrome 86+ + // Height set through cssText does not get applied. + // Computed height then comes back as 0. + tr.style.height = "1px"; + trChild.style.height = "9px"; + + // Support: Android 8 Chrome 86+ + // In our bodyBackground.html iframe, + // display for all div elements is set to "inline", + // which causes a problem only in Android 8 Chrome 86. + // Ensuring the div is display: block + // gets around this issue. + trChild.style.display = "block"; + + documentElement + .appendChild( table ) + .appendChild( tr ) + .appendChild( trChild ); + + trStyle = window.getComputedStyle( tr ); + reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + + parseInt( trStyle.borderTopWidth, 10 ) + + parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight; + + documentElement.removeChild( table ); + } + return reliableTrDimensionsVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !isAttached( elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; + +// Return a vendor-prefixed property or undefined +function vendorPropName( name ) { + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property +function finalPropName( name ) { + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + + if ( final ) { + return final; + } + if ( name in emptyStyle ) { + return name; + } + return vendorProps[ name ] = vendorPropName( name ) || name; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; + +function setPositiveNumber( _elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + + // Support: IE 9 - 11 only + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. + if ( ( !support.boxSizingReliable() && isBorderBox || + + // Support: IE 10 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Interestingly, in some cases IE 9 doesn't suffer from this issue. + !support.reliableTrDimensions() && nodeName( elem, "tr" ) || + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + val === "auto" || + + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + + // Make sure the element is visible & connected + elem.getClientRects().length ) { + + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "gridArea": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnStart": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowStart": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( _i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + + // Handle: regular nodes (via `this.ownerDocument`), window + // (via `this.document`) & document (via `this`). + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = { guid: Date.now() }; + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml, parserErrorElem; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) {} + + parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; + if ( !xml || parserErrorElem ) { + jQuery.error( "Invalid XML: " + ( + parserErrorElem ? + jQuery.map( parserErrorElem.childNodes, function( el ) { + return el.textContent; + } ).join( "\n" ) : + data + ) ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + if ( a == null ) { + return ""; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ).filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ).map( function( _i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + +originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() + " " ] = + ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) + .concat( match[ 2 ] ); + } + } + match = responseHeaders[ key.toLowerCase() + " " ]; + } + return match == null ? null : match.join( ", " ); + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Use a noop converter for missing script but not if jsonp + if ( !isSuccess && + jQuery.inArray( "script", s.dataTypes ) > -1 && + jQuery.inArray( "json", s.dataTypes ) < 0 ) { + s.converters[ "text script" ] = function() {}; + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( _i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + +jQuery.ajaxPrefilter( function( s ) { + var i; + for ( i in s.headers ) { + if ( i.toLowerCase() === "content-type" ) { + s.contentType = s.headers[ i ] || ""; + } + } +} ); + + +jQuery._evalUrl = function( url, options, doc ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + + // Only evaluate the response if it is successful (gh-4126) + // dataFilter is not invoked for failure responses, so using it instead + // of the default converter is kludgy but it works. + converters: { + "text script": function() {} + }, + dataFilter: function( response ) { + jQuery.globalEval( response, options, doc ); + } + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain or forced-by-attrs requests + if ( s.crossDomain || s.scriptAttrs ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " + + + + diff --git a/public/tags/arctic-data-center/index.xml b/public/tags/arctic-data-center/index.xml new file mode 100644 index 00000000..8b872a72 --- /dev/null +++ b/public/tags/arctic-data-center/index.xml @@ -0,0 +1,173 @@ + + + + Arctic Data Center on NCEAS Training Materials Catalog + /tags/arctic-data-center/ + Recent content in Arctic Data Center on NCEAS Training Materials Catalog + Hugo -- gohugo.io + en-us + Thu, 23 Mar 2023 00:00:00 +0000 + + + + + + Scalable and Computationally Reproducible Approaches to Arctic Research + /events/2023-03-arctic/ + Thu, 23 Mar 2023 00:00:00 +0000 + + /events/2023-03-arctic/ + Dates: March 27-31, 2023 +Location: NCEAS Venue: Santa Barbara, CA +This 5-day in-person workshop will provide researchers with an introduction to advanced topics in computationally reproducible research in python, including software and techniques for working with very large datasets. This includes working in cloud computing environments, docker containers, and parallel processing using tools like parsl and dask. The workshop will also cover concrete methods for documenting and uploading data to the Arctic Data Center, advanced approaches to tracking data provenance, responsible research and data management practices including data sovereignty and the CARE principles, and ethical concerns with data-intensive modeling and analysis. + + + + Reproducible Practices for Arctic Research Using R + /events/2023-02-arctic/ + Mon, 27 Feb 2023 00:00:00 +0000 + + /events/2023-02-arctic/ + Dates: February 27 - March 3, 2023 +Location: Online +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara +This 5-day remote workshop will provided researchers with an overview of best data management practices, data science tools for cleaning and analyzing data, and concrete steps and methods for more easily documenting and preserving their data at the Arctic Data Center. Example tools included R, Rmarkdown, and git/GitHub. This course provided background in both the theory and practice of reproducible research, spanning all portions of the research lifecycle, from ethical data collection following the CARE principles to engage with local stakeholders, to data publishing. + + + + Fundamentals in Data Management for Qualitative and Quantitative Arctic Research + /events/2023-01-arctic/ + Mon, 30 Jan 2023 00:00:00 +0000 + + /events/2023-01-arctic/ + Dates: January 30 - February 3, 2023 +Location: NCEAS Venue: Santa Barbara, CA +This 5-day in-person workshop will provide researchers with an overview of reproducible and ethical research practices, steps and methods for more easily documenting and preserving their data at the Arctic Data Center, and an introduction to programming in R. Special attention will be paid to qualitative data management, including practices working with sensitive data. Example datasets will draw from natural and social sciences, and methods for conducting reproducible research will be discussed in the context of both qualitative and quantitative data. + + + + Scalable and Computationally Reproducible Approaches to Arctic Research + /events/2022-09-arctic/ + Sun, 18 Sep 2022 00:00:00 +0000 + + /events/2022-09-arctic/ + Dates: September 19 - 23, 2022 +Location: NCEAS Venue: Santa Barbara, CA +This 5-day in-person workshop will provide researchers with an introduction to advanced topics in computationally reproducible research in python, including software and techniques for working with very large datasets. This includes working in cloud computing environments, docker containers, and parallel processing using tools like parsl and dask. The workshop will also cover concrete methods for documenting and uploading data to the Arctic Data Center, advanced approaches to tracking data provenance, responsible research and data management practices including data sovereignty and the CARE principles, and ethical concerns with data-intensive modeling and analysis. + + + + Fundamentals in Data Management for Qualitative and Quantitative Arctic Research + /events/2022-04-arctic/ + Mon, 18 Apr 2022 00:00:00 +0000 + + /events/2022-04-arctic/ + Dates: April 18 - 22, 2022 +Location: NCEAS Venue: Santa Barbara, CA +This 5-day in-person workshop will provide researchers with an overview of reproducible and ethical research practices, steps and methods for more easily documenting and preserving their data at the Arctic Data Center, and an introduction to programming in R. Special attention will be paid to qualitative data management, including practices working with sensitive data. Example datasets will draw from natural and social sciences, and methods for conducting reproducible research will be discussed in the context of both qualitative and quantitative data. + + + + Arctic Data Center Training (February 2022) + /events/2022_02_arctic/ + Mon, 14 Feb 2022 00:00:00 +0000 + + /events/2022_02_arctic/ + Dates: February 14 - February 19, 2022 +Location: Online +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara The Arctic Data Center provides training in data science and data management, as these are critical skills for the stewardship of the data, software, and other research products that are preserved in the Arctic Data Center. A goal of the Arctic Data Center is to advance data archiving and promote reproducible science and data reuse. + + + + Open Science: Best Practices, Data Sovereignty and Co-production + /events/2022_03_arctic/ + Mon, 14 Feb 2022 00:00:00 +0000 + + /events/2022_03_arctic/ + Dates: March 29, 2022 +Location: Arctic Science Summit Week +Venue: Tromso, Norway +This workshop is a collaboration between the Arctic Data Center, ELOKA and the NNA Community Office, and will focus on the presentation of open science principles and best practices. Open science will be explored from the lens of reproducibility of research, Indigenous data sovereignty, and community data management. A combination of presentation and discussion will introduce participants to key topics, detail current recommended practices and highlight areas for future research. + + + + Arctic Data Center Training (October 2020) + /events/2020_10_arctic/ + Mon, 19 Oct 2020 00:00:00 +0000 + + /events/2020_10_arctic/ + Dates: October 19 - October 23, 2020 +Location: Online +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara The Arctic Data Center provides training in data science and data management, as these are critical skills for the stewardship of the data, software, and other research products that are preserved in the Arctic Data Center. A goal of the Arctic Data Center is to advance data archiving and promote reproducible science and data reuse. + + + + Arctic Data Center Training (October 2019) + /events/2019_10_arctic/ + Mon, 07 Oct 2019 00:00:00 +0000 + + /events/2019_10_arctic/ + Dates: October 7 - October 11, 2019 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara The Arctic Data Center provides training in data science and data management, as these are critical skills for the stewardship of the data, software, and other research products that are preserved in the Arctic Data Center. A goal of the Arctic Data Center is to advance data archiving and promote reproducible science and data reuse. + + + + Arctic Data Center Training (February 2019) + /events/2019_02_arctic/ + Mon, 11 Feb 2019 00:00:00 +0000 + + /events/2019_02_arctic/ + Dates: February 11 - February 15, 2019 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara The Arctic Data Center provides training in data science and data management, as these are critical skills for the stewardship of the data, software, and other research products that are preserved in the Arctic Data Center. A goal of the Arctic Data Center is to advance data archiving and promote reproducible science and data reuse. + + + + Arctic Data Center Training (January 2019) + /events/2019_01_arctic/ + Mon, 14 Jan 2019 00:00:00 +0000 + + /events/2019_01_arctic/ + Dates: January 14 - January 18, 2019 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara The Arctic Data Center provides training in data science and data management, as these are critical skills for the stewardship of the data, software, and other research products that are preserved in the Arctic Data Center. A goal of the Arctic Data Center is to advance data archiving and promote reproducible science and data reuse. + + + + Arctic Data Center Training (August 2018) + /events/2018_08_arctic/ + Mon, 13 Aug 2018 00:00:00 +0000 + + /events/2018_08_arctic/ + Dates: August 13 - August 17, 2018 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara The Arctic Data Center provides training in data science and data management, as these are critical skills for the stewardship of the data, software, and other research products that are preserved in the Arctic Data Center. A goal of the Arctic Data Center is to advance data archiving and promote reproducible science and data reuse. + + + + Dataset Publishing with the Arctic Data Center (June 2018) + /events/2018_06_arctic/ + Fri, 22 Jun 2018 00:00:00 +0000 + + /events/2018_06_arctic/ + Dates: June 22, 2018 12:30 to 14:00 +Location: Davos, Switzerland +Venue: POLAR 2018 Open Science Conference +This hands-on session will cover (1) Open data archives, especially the Arctic Data Center; (2) What science metadata is and how it can be used; (3) How data and code can be documented and published in open data archives; (4) Web-based submission, and (5) Submission using R (pending sufficient time). +Course overview The Arctic Data Center conducts training in data science and management, both of which are critical skills for stewardship of data, software, and other products of research that are preserved at the Arctic Data Center. + + + + Tools for Data Science in Arctic Research (July 2017) + /events/2017_07_arctic/ + Mon, 31 Jul 2017 00:00:00 +0000 + + /events/2017_07_arctic/ + Dates: July 31 - Aug 1, 2017 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara The Arctic Data Center provides training in data science and data management, as these are critical skills for the stewardship of the data, software, and other research products that are preserved in the Arctic Data Center. A goal of the Arctic Data Center is to advance data archiving and promote reproducible science and data reuse. + + + + \ No newline at end of file diff --git a/public/tags/collaborative/index.html b/public/tags/collaborative/index.html new file mode 100644 index 00000000..3cc63a51 --- /dev/null +++ b/public/tags/collaborative/index.html @@ -0,0 +1,285 @@ + + + + + + + Collaborative Efforts | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+

+ Collaborative Efforts +

+ +

+ The Learning Hub hosts many collaborative events with other partners, including NEON and the Delta Preservation Council. +

+ +
+
+
+ + +
+ + +
+ +
+
+ +
+
+
+

+ + Open Science Synthesis for the Delta Science Program + +

+ +
+
+ +
+ +
+
+
+

+ + Open Science Synthesis for the Delta Science Program + +

+ +
+
+ +
+ +
+
+
+

+ + NEON Onboarding + +

+ +
+
+ +
+ +
+
+ +
+ + + + + + + + + diff --git a/public/tags/collaborative/index.xml b/public/tags/collaborative/index.xml new file mode 100644 index 00000000..a357645e --- /dev/null +++ b/public/tags/collaborative/index.xml @@ -0,0 +1,43 @@ + + + + Collaborative Efforts on NCEAS Training Materials Catalog + /tags/collaborative/ + Recent content in Collaborative Efforts on NCEAS Training Materials Catalog + Hugo -- gohugo.io + en-us + Mon, 26 Jun 2023 00:00:00 +0000 + + + + + + Open Science Synthesis for the Delta Science Program + /events/2023-06-delta/ + Mon, 26 Jun 2023 00:00:00 +0000 + + /events/2023-06-delta/ + In collaboration with the Delta Science Program we are running a 12 month facilitated research synthesis activity, supported by 3 one-week intensive training events. Curriculum material will focus on introducing Delta Researchers to best practices in, and application of, scientific computing and scientific software for reproducible science. In addition to developing and delivering learning curriculum, this collaboration will include the provision of data consulting, synthesis facilitation, and a remote workshop to conclude the group synthesis activities. + + + + Open Science Synthesis for the Delta Science Program + /events/2021_09_delta/ + Thu, 27 May 2021 00:00:00 +0000 + + /events/2021_09_delta/ + In collaboration with the Delta Science Program we are running a 12 month facilitated research synthesis activity, supported by 3 one-week intensive training events. Curriculum material will focus on introducing Delta Researchers to best practices in, and application of, scientific computing and scientific software for reproducible science. In addition to developing and delivering learning curriculum, this collaboration will include the provision of data consulting, synthesis facilitation, and a remote workshop to conclude the group synthesis activities. + + + + NEON Onboarding + /events/2020_12_neon/ + Tue, 01 Dec 2020 00:00:00 +0000 + + /events/2020_12_neon/ + Dates: December, 2020 Location: Virtual NEON Onboarding A self guided learning curricula to support new NEON postdocs as part of their onboarding experience. The curricula builds from the experience of ecological researchers, trainers, developers and information managers to provide resources and training in support of collaborative, reproducible research practices. +Materials Link to onboarding materials + + + + \ No newline at end of file diff --git a/public/tags/conference/index.html b/public/tags/conference/index.html new file mode 100644 index 00000000..8fa1c209 --- /dev/null +++ b/public/tags/conference/index.html @@ -0,0 +1,235 @@ + + + + + + + Conference | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+

+ Conference +

+ +

+ The Learning Hub occasionally presents workshops at conferences such as ESA and AGU. +

+ +
+
+
+ + +
+ + +
+ + + + + + + + + diff --git a/public/tags/conference/index.xml b/public/tags/conference/index.xml new file mode 100644 index 00000000..001a9d54 --- /dev/null +++ b/public/tags/conference/index.xml @@ -0,0 +1,14 @@ + + + + Conference on NCEAS Training Materials Catalog + /tags/conference/ + Recent content in Conference on NCEAS Training Materials Catalog + Hugo -- gohugo.io + en-us + + + + + + \ No newline at end of file diff --git a/public/tags/conferences/index.html b/public/tags/conferences/index.html new file mode 100644 index 00000000..ce95ad77 --- /dev/null +++ b/public/tags/conferences/index.html @@ -0,0 +1,249 @@ + + + + + + + Conferences | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+

+ Conferences +

+ +
+
+
+ + +
+ + +
+ +
+
+ +
+
+
+

+ + Managing Ecological Data for Effective Use and Re-Use + +

+ +
+
+ +
+ +
+
+ +
+ + + + + + + + + diff --git a/public/tags/conferences/index.xml b/public/tags/conferences/index.xml new file mode 100644 index 00000000..dc06fcd4 --- /dev/null +++ b/public/tags/conferences/index.xml @@ -0,0 +1,25 @@ + + + + Conferences on NCEAS Training Materials Catalog + /tags/conferences/ + Recent content in Conferences on NCEAS Training Materials Catalog + Hugo -- gohugo.io + en-us + Wed, 28 Jul 2021 00:00:00 +0000 + + + + + + Managing Ecological Data for Effective Use and Re-Use + /events/2021_08_esa/ + Wed, 28 Jul 2021 00:00:00 +0000 + + /events/2021_08_esa/ + Friday, August 6th, 2021 10:30 AM - 1:30 PM +Session Description While graduate students in ecology learn about methods for collecting and analyzing ecological data, there is less emphasis on managing and using the resulting data effectively. This is an increasingly important skill set as the research landscape changes. Researchers are increasingly engaging in collaboration across networks, many funding agencies require data management plans, journals are requiring that data and code be accessible, and society is increasingly expecting that research be reproducible. + + + + \ No newline at end of file diff --git a/public/tags/index.html b/public/tags/index.html new file mode 100644 index 00000000..3001df8f --- /dev/null +++ b/public/tags/index.html @@ -0,0 +1,801 @@ + + + + + + + NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+

+ Tags +

+ +
+
+
+ + +
+ + +
+ +
+
+
+ +

+ + Tag: arctic-data-center + +

+ +
+
+

+ + Scalable and Computationally Reproducible Approaches to Arctic Research + +

+ +
+
+ + +
+
+

+ + Reproducible Practices for Arctic Research Using R + +

+ +
+
+ + +
+
+

+ + Fundamentals in Data Management for Qualitative and Quantitative Arctic Research + +

+ +
+
+ + +
+
+

+ + Scalable and Computationally Reproducible Approaches to Arctic Research + +

+ +
+
+ + +
+
+

+ + Fundamentals in Data Management for Qualitative and Quantitative Arctic Research + +

+ +
+
+ + +
+
+

+ + Arctic Data Center Training (February 2022) + +

+ +
+
+ + +
+
+

+ + Open Science: Best Practices, Data Sovereignty and Co-production + +

+ +
+
+ + +
+
+

+ + Arctic Data Center Training (October 2020) + +

+ +
+
+ + +
+
+

+ + Arctic Data Center Training (October 2019) + +

+ +
+
+ + +
+
+

+ + Arctic Data Center Training (February 2019) + +

+ +
+
+ + +
+
+

+ + Arctic Data Center Training (January 2019) + +

+ +
+
+ + +
+
+

+ + Arctic Data Center Training (August 2018) + +

+ +
+
+ + +
+
+

+ + Dataset Publishing with the Arctic Data Center (June 2018) + +

+ +
+
+ + +
+
+

+ + Tools for Data Science in Arctic Research (July 2017) + +

+ +
+
+ + + +

+ + Tag: collaborative + +

+ +
+
+

+ + Open Science Synthesis for the Delta Science Program + +

+ +
+
+ + +
+
+

+ + Open Science Synthesis for the Delta Science Program + +

+ +
+
+ + +
+
+

+ + NEON Onboarding + +

+ +
+
+ + + +

+ + Tag: conferences + +

+ +
+
+

+ + Managing Ecological Data for Effective Use and Re-Use + +

+ +
+
+ + + +

+ + Tag: lter + +

+ +
+
+

+ + Tools and practices for collaborative, reproducible data science + +

+ +
+
+ + +
+
+

+ + Efficient virtual collaboration & facilitation for synthesis science + +

+ +
+
+ + + +

+ + Tag: openscapes + +

+ +
+
+

+ + Openscapes Champions Workshop with NOAA + +

+ +
+
+ + +
+
+

+ + Openscapes Champions Cohort sponsored by Mozilla + +

+ +
+
+ + + +

+ + Tag: oss + +

+ +
+
+

+ + Open Science Synthesis for the Delta Science Program + +

+ +
+
+ + +
+
+

+ + Open Science Synthesis for the Delta Science Program + +

+ +
+
+ + +
+
+

+ + Open Science for Synthesis: Gulf Research Program Workshop + +

+ +
+
+ + + +

+ + Tag: short-course + +

+ +
+
+

+ + NCEAS Learning Hub coreR Course + +

+ +
+
+ + +
+
+

+ + Reproducible Research Techniques for Synthesis (November 2021) + +

+ +
+
+ + +
+
+

+ + Reproducible Research Techniques for Synthesis (July 2021) + +

+ +
+
+ + +
+
+

+ + Reproducible Research Techniques for Synthesis (February 2021) + +

+ +
+
+ + +
+
+

+ + Reproducible Research Techniques for Synthesis (November 2020) + +

+ +
+
+ + +
+
+

+ + Reproducible Research Techniques for Synthesis (February 2020) + +

+ +
+
+ + +
+
+

+ + Reproducible Research Techniques for Synthesis (November 2019) + +

+ +
+
+ + + +

+ + Tag: snapp + +

+ +
+
+

+ + Tools and practices for collaborative, reproducible data science + +

+ +
+
+ + +
+
+

+ + Efficient virtual collaboration & facilitation for synthesis science + +

+ +
+
+ + +
+
+

+ + Data Science and Collaboration Skills for Integrative Conservation Science + +

+ +
+
+ + + +
+
+ +
+ + + + + + + + + diff --git a/public/tags/index.xml b/public/tags/index.xml new file mode 100644 index 00000000..b77651ec --- /dev/null +++ b/public/tags/index.xml @@ -0,0 +1,96 @@ + + + + Tags on NCEAS Training Materials Catalog + /tags/ + Recent content in Tags on NCEAS Training Materials Catalog + Hugo -- gohugo.io + en-us + Mon, 26 Jun 2023 00:00:00 +0000 + + + + + + Collaborative Efforts + /tags/collaborative/ + Mon, 26 Jun 2023 00:00:00 +0000 + + /tags/collaborative/ + + + + + Open Science for Synthesis + /tags/oss/ + Mon, 26 Jun 2023 00:00:00 +0000 + + /tags/oss/ + + + + + Short Course + /tags/short-course/ + Mon, 03 Apr 2023 00:00:00 +0000 + + /tags/short-course/ + + + + + Arctic Data Center + /tags/arctic-data-center/ + Thu, 23 Mar 2023 00:00:00 +0000 + + /tags/arctic-data-center/ + + + + + Conferences + /tags/conferences/ + Wed, 28 Jul 2021 00:00:00 +0000 + + /tags/conferences/ + + + + + Long Term Ecological Research Network + /tags/lter/ + Fri, 08 May 2020 00:00:00 +0000 + + /tags/lter/ + + + + + Science for Nature and People Partnership + /tags/snapp/ + Fri, 08 May 2020 00:00:00 +0000 + + /tags/snapp/ + + + + + Openscapes + /tags/openscapes/ + Wed, 26 Feb 2020 00:00:00 +0000 + + /tags/openscapes/ + + + + + Conference + /tags/conference/ + Mon, 01 Jan 0001 00:00:00 +0000 + + /tags/conference/ + + + + + \ No newline at end of file diff --git a/public/tags/lter/index.html b/public/tags/lter/index.html new file mode 100644 index 00000000..974f4d78 --- /dev/null +++ b/public/tags/lter/index.html @@ -0,0 +1,270 @@ + + + + + + + Long Term Ecological Research Network | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+

+ Long Term Ecological Research Network +

+ +

+ NCEAS operates the LTER Network Office, which serves as a hub for LTER synthesis research, education, and outreach activities. NCEAS hosts training events aimed towards LTER working group participants. +

+ +
+
+
+ + +
+ + +
+ +
+
+ +
+
+
+

+ + Tools and practices for collaborative, reproducible data science + +

+ +
+
+ +
+ +
+
+
+

+ + Efficient virtual collaboration & facilitation for synthesis science + +

+ +
+
+ +
+ +
+
+ +
+ + + + + + + + + diff --git a/public/tags/lter/index.xml b/public/tags/lter/index.xml new file mode 100644 index 00000000..1a17cfb3 --- /dev/null +++ b/public/tags/lter/index.xml @@ -0,0 +1,35 @@ + + + + Long Term Ecological Research Network on NCEAS Training Materials Catalog + /tags/lter/ + Recent content in Long Term Ecological Research Network on NCEAS Training Materials Catalog + Hugo -- gohugo.io + en-us + Fri, 08 May 2020 00:00:00 +0000 + + + + + + Tools and practices for collaborative, reproducible data science + /events/2020_05_nceaswg/ + Fri, 08 May 2020 00:00:00 +0000 + + /events/2020_05_nceaswg/ + Dates: May 8, 2020 +Location: Remote This module is an introduction to the data science support NCEAS is providing to LTER and SNAPP working groups followed by a discussion on best practices about data management in a distributed team setup. Participants will have the opportunity to brainstorm on their data and computing needs. In the second part of the workshop, an introduction to the use of NCEAS analytical server and the concept of collaborative coding as a distributed team will be demonstrated to empower participants to develop their analytical workflows in a remote setup. + + + + Efficient virtual collaboration & facilitation for synthesis science + /events/2020_04_nceaswg/ + Fri, 24 Apr 2020 00:00:00 +0000 + + /events/2020_04_nceaswg/ + Dates: April 24, 2020 +Location: Remote This 3-hour module provides mentorship and facilitation training for Working Groups to develop skill sets, habits, and mindsets to make remote work and collaborative synthesis science more efficient and resilient. + + + + \ No newline at end of file diff --git a/public/tags/openscapes/index.html b/public/tags/openscapes/index.html new file mode 100644 index 00000000..9bf4ebbb --- /dev/null +++ b/public/tags/openscapes/index.html @@ -0,0 +1,272 @@ + + + + + + + Openscapes | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+

+ Openscapes +

+ +

+ Openscapes champions open practices in environmental science to help uncover data-driven solutions faster. This is a listing of Openscapes events. +

+ +
+
+
+ + +
+ + +
+ +
+
+ +
+
+
+

+ + Openscapes Champions Workshop with NOAA + +

+ +
+
+ +
+ +
+
+
+

+ + Openscapes Champions Cohort sponsored by Mozilla + +

+ +
+
+ +
+ +
+
+ +
+ + + + + + + + + diff --git a/public/tags/openscapes/index.xml b/public/tags/openscapes/index.xml new file mode 100644 index 00000000..5d50f1fd --- /dev/null +++ b/public/tags/openscapes/index.xml @@ -0,0 +1,37 @@ + + + + Openscapes on NCEAS Training Materials Catalog + /tags/openscapes/ + Recent content in Openscapes on NCEAS Training Materials Catalog + Hugo -- gohugo.io + en-us + Wed, 26 Feb 2020 00:00:00 +0000 + + + + + + Openscapes Champions Workshop with NOAA + /events/2020_02_openscapes/ + Wed, 26 Feb 2020 00:00:00 +0000 + + /events/2020_02_openscapes/ + Dates: February 26 - February 27, 2020 +Location: Woods Hole, Massachusetts. NOAA Northeast Fisheries Science Center. Through in-person Workshops, cohorts of research groups participate over a 2 full days. Workshops are designed to be engaging, requiring active participation through discussion, live-notetaking in Google Docs, and breakout group activities. +Openscapes is operated by the National Center for Ecological Analysis &amp; Synthesis (NCEAS) and is being incubated by a Mozilla Fellowship awarded to Julia Stewart Lowndes. + + + + Openscapes Champions Cohort sponsored by Mozilla + /events/2019_01_openscapes/ + Thu, 10 Jan 2019 00:00:00 +0000 + + /events/2019_01_openscapes/ + Dates: January 10 - May 24, 2019 +Location: Remote In the Long-term Remote Program, Cohorts of research groups participate over a four-month period, with two Cohort Calls each month. Calls are designed to be engaging, requiring discussion and active participation through live-notetaking in Google Docs and video Zoom (group and breakouts). +Openscapes is operated by the National Center for Ecological Analysis &amp; Synthesis (NCEAS) and is being incubated by a Mozilla Fellowship awarded to Julia Stewart Lowndes. + + + + \ No newline at end of file diff --git a/public/tags/oss/index.html b/public/tags/oss/index.html new file mode 100644 index 00000000..e06995d1 --- /dev/null +++ b/public/tags/oss/index.html @@ -0,0 +1,288 @@ + + + + + + + Open Science for Synthesis | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+

+ Open Science for Synthesis +

+ +

+ OSS courses are 3 weeks long, and geared towards early career researchers. Participants engage in a mix of lectures, exercises, and original group synthesis research - all geared towards learning and implementing best practices for open science. +

+ +
+
+
+ + +
+ + +
+ +
+
+ +
+
+
+

+ + Open Science Synthesis for the Delta Science Program + +

+ +
+
+ +
+ +
+
+
+

+ + Open Science Synthesis for the Delta Science Program + +

+ +
+
+ +
+ +
+
+
+

+ + Open Science for Synthesis: Gulf Research Program Workshop + +

+ +
+
+ +
+ +
+
+ +
+ + + + + + + + + diff --git a/public/tags/oss/index.xml b/public/tags/oss/index.xml new file mode 100644 index 00000000..944ab8a9 --- /dev/null +++ b/public/tags/oss/index.xml @@ -0,0 +1,46 @@ + + + + Open Science for Synthesis on NCEAS Training Materials Catalog + /tags/oss/ + Recent content in Open Science for Synthesis on NCEAS Training Materials Catalog + Hugo -- gohugo.io + en-us + Mon, 26 Jun 2023 00:00:00 +0000 + + + + + + Open Science Synthesis for the Delta Science Program + /events/2023-06-delta/ + Mon, 26 Jun 2023 00:00:00 +0000 + + /events/2023-06-delta/ + In collaboration with the Delta Science Program we are running a 12 month facilitated research synthesis activity, supported by 3 one-week intensive training events. Curriculum material will focus on introducing Delta Researchers to best practices in, and application of, scientific computing and scientific software for reproducible science. In addition to developing and delivering learning curriculum, this collaboration will include the provision of data consulting, synthesis facilitation, and a remote workshop to conclude the group synthesis activities. + + + + Open Science Synthesis for the Delta Science Program + /events/2021_09_delta/ + Thu, 27 May 2021 00:00:00 +0000 + + /events/2021_09_delta/ + In collaboration with the Delta Science Program we are running a 12 month facilitated research synthesis activity, supported by 3 one-week intensive training events. Curriculum material will focus on introducing Delta Researchers to best practices in, and application of, scientific computing and scientific software for reproducible science. In addition to developing and delivering learning curriculum, this collaboration will include the provision of data consulting, synthesis facilitation, and a remote workshop to conclude the group synthesis activities. + + + + Open Science for Synthesis: Gulf Research Program Workshop + /events/2017_07_oss/ + Mon, 10 Jul 2017 00:00:00 +0000 + + /events/2017_07_oss/ + Dates: July 10 - July 28, 2017 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara +The primary goal of the Open Science for Synthesis: Gulf Research Program Workshop is to provide hands-on experience with contemporary open science tools from command line to data to communication. Team science is promoted. Practice and real data are used in groups to apply skills we explore. +Week 1. + + + + \ No newline at end of file diff --git a/public/tags/short-course/index.html b/public/tags/short-course/index.html new file mode 100644 index 00000000..d77717e9 --- /dev/null +++ b/public/tags/short-course/index.html @@ -0,0 +1,366 @@ + + + + + + + Short Course | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+

+ Short Course +

+ +

+ These 5-day courses provide researchers with an overview of best data management practices, data science tools, and concrete steps to more easily produce transparent, reproducible workflows. Courses are open to anyone. +

+ +
+
+
+ + +
+ + +
+ +
+
+ +
+
+
+

+ + NCEAS Learning Hub coreR Course + +

+ +
+
+ +
+ +
+
+
+

+ + Reproducible Research Techniques for Synthesis (November 2021) + +

+ +
+
+ +
+ +
+
+
+

+ + Reproducible Research Techniques for Synthesis (July 2021) + +

+ +
+
+ +
+ +
+
+
+

+ + Reproducible Research Techniques for Synthesis (February 2021) + +

+ +
+
+ +
+ +
+
+
+

+ + Reproducible Research Techniques for Synthesis (November 2020) + +

+ +
+
+ +
+ +
+
+
+

+ + Reproducible Research Techniques for Synthesis (February 2020) + +

+ +
+
+ +
+ +
+
+
+

+ + Reproducible Research Techniques for Synthesis (November 2019) + +

+ +
+
+ +
+ +
+
+ +
+ + + + + + + + + diff --git a/public/tags/short-course/index.xml b/public/tags/short-course/index.xml new file mode 100644 index 00000000..42f04b54 --- /dev/null +++ b/public/tags/short-course/index.xml @@ -0,0 +1,96 @@ + + + + Short Course on NCEAS Training Materials Catalog + /tags/short-course/ + Recent content in Short Course on NCEAS Training Materials Catalog + Hugo -- gohugo.io + en-us + Mon, 03 Apr 2023 00:00:00 +0000 + + + + + + NCEAS Learning Hub coreR Course + /events/2023-04-corer/ + Mon, 03 Apr 2023 00:00:00 +0000 + + /events/2023-04-corer/ + Previously called the Reproducible Research Techniques for Synthesis course +Dates: April 3-7, 2023 +Location: NCEAS Venue: Santa Barbara, CA +A five-day immersion in R programming for environmental data science. Researchers will gain experience with essential data science tools and best practices to increase their capacity as collaborators, reproducible coders, and open scientists. This course is taught both in-person and virtually. +Materials Link to course book +Instructors Name Email Halina Do-Linh dolinh@nceas. + + + + Reproducible Research Techniques for Synthesis (November 2021) + /events/2021_11_nceas/ + Fri, 05 Nov 2021 00:00:00 +0000 + + /events/2021_11_nceas/ + Dates: November 15-19, 2021 +Location: Remote +This 5-day workshop will provide researchers with an overview of best data management practices, data science tools, and concrete steps and methods for more easily producing transparent, reproducible workflows. This opportunity is for researchers from across career stages and sectors who want to gain fundamental data science skills that will improve their reproducible research techniques, particularly for the purposes of synthesis science. +Curriculum at a glance: Enable data reuse through better data management Metadata - what is it and how to write a quality data description Data modeling - tidy data for efficient access and storage Data publishing, citation, and credit Build reproducible scientific workflows Data munging with R tidyverse Working collaboratively - git and GitHub Writing functions in R Building packages for publishing reproducible research Communicate results effectively Literate analysis with RMarkdown Publishing analytical web pages with GitHub pages Data visualization with ggplot and leaflet For more detailed information on how to prepare for the workshop, see preparing for the workshop (below). + + + + Reproducible Research Techniques for Synthesis (July 2021) + /events/2021_07_nceas/ + Tue, 25 May 2021 00:00:00 +0000 + + /events/2021_07_nceas/ + Dates: July 8-9, 12-14, 2021 +Location: Remote +This 5-day workshop will provide researchers with an overview of best data management practices, data science tools, and concrete steps and methods for more easily producing transparent, reproducible workflows. This opportunity is for researchers from across career stages and sectors who want to gain fundamental data science skills that will improve their reproducible research techniques, particularly for the purposes of synthesis science. + + + + Reproducible Research Techniques for Synthesis (February 2021) + /events/2021_02_nceas/ + Fri, 05 Feb 2021 00:00:00 +0000 + + /events/2021_02_nceas/ + Dates: February 25-26, March 1-3, 2021 +Location: Remote +This 5-day workshop will provide researchers with an overview of best data management practices, data science tools, and concrete steps and methods for more easily producing transparent, reproducible workflows. This opportunity is for researchers from across career stages and sectors who want to gain fundamental data science skills that will improve their reproducible research techniques, particularly for the purposes of synthesis science. + + + + Reproducible Research Techniques for Synthesis (November 2020) + /events/2020_11_nceas/ + Thu, 12 Nov 2020 00:00:00 +0000 + + /events/2020_11_nceas/ + Dates: November 12 - November 18, 2020 +Location: Remote +This 5-day workshop will provide researchers with an overview of best data management practices, data science tools, and concrete steps and methods for more easily producing transparent, reproducible workflows. This opportunity is for researchers from across career stages and sectors who want to gain fundamental data science skills that will improve their reproducible research techniques, particularly for the purposes of synthesis science. + + + + Reproducible Research Techniques for Synthesis (February 2020) + /events/2020_02_nceas/ + Mon, 03 Feb 2020 00:00:00 +0000 + + /events/2020_02_nceas/ + Dates: February 3 - February 7, 2020 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara This 5-day workshop will provide researchers with an overview of best data management practices, data science tools, and concrete steps and methods for more easily producing transparent, reproducible workflows. This opportunity is for researchers from across career stages and sectors who want to gain fundamental data science skills that will improve their reproducible research techniques, particularly for the purposes of synthesis science. + + + + Reproducible Research Techniques for Synthesis (November 2019) + /events/2019_11_nceas/ + Mon, 04 Nov 2019 00:00:00 +0000 + + /events/2019_11_nceas/ + Dates: November 4 - November 8, 2019 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara This 5-day workshop will provide researchers with an overview of best data management practices, data science tools, and concrete steps and methods for more easily producing transparent, reproducible workflows. This opportunity is for researchers from across career stages and sectors who want to gain fundamental data science skills that will improve their reproducible research techniques, particularly for the purposes of synthesis science. + + + + \ No newline at end of file diff --git a/public/tags/snapp/index.html b/public/tags/snapp/index.html new file mode 100644 index 00000000..1ba0e250 --- /dev/null +++ b/public/tags/snapp/index.html @@ -0,0 +1,290 @@ + + + + + + + Science for Nature and People Partnership | NCEAS Training Materials Catalog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+

+ Science for Nature and People Partnership +

+ +

+ SNAPP is a collaboration between The Nature Conservancy, the Wildlife Conservation Society, and NCEAS to deliver evidence based solutions to address global challenges. NCEAS runs training events sponsored by SNAPP and aimed for SNAPP working group participants. +

+ +
+
+
+ + +
+ + +
+ +
+
+ +
+
+
+

+ + Tools and practices for collaborative, reproducible data science + +

+ +
+
+ +
+ +
+
+
+

+ + Efficient virtual collaboration & facilitation for synthesis science + +

+ +
+
+ +
+ +
+
+
+

+ + Data Science and Collaboration Skills for Integrative Conservation Science + +

+ +
+
+ +
+ +
+
+ +
+ + + + + + + + + diff --git a/public/tags/snapp/index.xml b/public/tags/snapp/index.xml new file mode 100644 index 00000000..4bc7a742 --- /dev/null +++ b/public/tags/snapp/index.xml @@ -0,0 +1,48 @@ + + + + Science for Nature and People Partnership on NCEAS Training Materials Catalog + /tags/snapp/ + Recent content in Science for Nature and People Partnership on NCEAS Training Materials Catalog + Hugo -- gohugo.io + en-us + Fri, 08 May 2020 00:00:00 +0000 + + + + + + Tools and practices for collaborative, reproducible data science + /events/2020_05_nceaswg/ + Fri, 08 May 2020 00:00:00 +0000 + + /events/2020_05_nceaswg/ + Dates: May 8, 2020 +Location: Remote This module is an introduction to the data science support NCEAS is providing to LTER and SNAPP working groups followed by a discussion on best practices about data management in a distributed team setup. Participants will have the opportunity to brainstorm on their data and computing needs. In the second part of the workshop, an introduction to the use of NCEAS analytical server and the concept of collaborative coding as a distributed team will be demonstrated to empower participants to develop their analytical workflows in a remote setup. + + + + Efficient virtual collaboration & facilitation for synthesis science + /events/2020_04_nceaswg/ + Fri, 24 Apr 2020 00:00:00 +0000 + + /events/2020_04_nceaswg/ + Dates: April 24, 2020 +Location: Remote This 3-hour module provides mentorship and facilitation training for Working Groups to develop skill sets, habits, and mindsets to make remote work and collaborative synthesis science more efficient and resilient. + + + + Data Science and Collaboration Skills for Integrative Conservation Science + /events/2020_02_snapp/ + Tue, 18 Feb 2020 00:00:00 +0000 + + /events/2020_02_snapp/ + Dates: February 18 - February 21, 2020 +Location: Santa Barbara, CA +Venue: NCEAS, 735 State St., Suite 300, UC Santa Barbara +This intensive 4-day workshop on Data Science and Collaboration Skills for Integrative Conservation Science will be held at NCEAS, Santa Barbara, CA from Feb 18 to Feb 21, 2020. +This training, sponsored by SNAPP, aims to bring together the SNAPP and NCEAS postdoctoral associates to foster communities and collaboration, as well as promote scientific computing and open science best practices. + + + + \ No newline at end of file