diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/404.html b/404.html new file mode 100644 index 000000000..77f2b03c3 --- /dev/null +++ b/404.html @@ -0,0 +1,362 @@ + + + + + + +Page Not Found — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + +
+ + + + + +
+ +

Page Not Found

+ + +

bill and ted mime to socrates "dust. wind. dude."

+ +
+

Bill: All we are is dust in the wind.
+Ted: Dust. Wind. Dude.
+Socrates: gasp

+
+ +

Entropy strikes again!

+ +

The page you were trying to view is not here. Perhaps try searching for it below?

+ +
+
+
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/CNAME b/CNAME new file mode 100644 index 000000000..c9a4c7202 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +www.ryanpatrickrandall.com \ No newline at end of file diff --git a/Gemfile b/Gemfile new file mode 100644 index 000000000..5e8cb3685 --- /dev/null +++ b/Gemfile @@ -0,0 +1,21 @@ +source "https://rubygems.org" + +gem "github-pages", group: :jekyll_plugins +gem "jekyll-include-cache", group: :jekyll_plugins + +gem "tzinfo-data" +gem "wdm", "~> 0.1.0" if Gem.win_platform? +gem "activesupport", ">= 4.1.11" +gem "webrick" + +# If you have any plugins, put them here! +group :jekyll_plugins do + gem "jekyll-paginate" + gem "jekyll-sitemap" + gem "jekyll-gist" + gem "jekyll-feed" + gem "jemoji" +# gem "jekyll-include-cache" + gem "jekyll-algolia" + gem "github-pages-unscramble" +end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 000000000..10b929da1 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,298 @@ +GEM + remote: https://rubygems.org/ + specs: + activesupport (6.1.7.5) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 1.6, < 2) + minitest (>= 5.1) + tzinfo (~> 2.0) + zeitwerk (~> 2.3) + addressable (2.8.1) + public_suffix (>= 2.0.2, < 6.0) + algolia_html_extractor (2.6.4) + json (~> 2.0) + nokogiri (~> 1.10) + algoliasearch (1.27.5) + httpclient (~> 2.8, >= 2.8.3) + json (>= 1.5.1) + coffee-script (2.4.1) + coffee-script-source + execjs + coffee-script-source (1.11.1) + colorator (1.1.0) + commonmarker (0.23.10) + concurrent-ruby (1.2.2) + dnsruby (1.61.9) + simpleidn (~> 0.1) + em-websocket (0.5.3) + eventmachine (>= 0.12.9) + http_parser.rb (~> 0) + ethon (0.16.0) + ffi (>= 1.15.0) + eventmachine (1.2.7) + execjs (2.8.1) + faraday (2.7.4) + faraday-net_http (>= 2.0, < 3.1) + ruby2_keywords (>= 0.0.4) + faraday-net_http (3.0.2) + ffi (1.15.5) + filesize (0.2.0) + forwardable-extended (2.6.0) + gemoji (3.0.1) + github-pages (228) + github-pages-health-check (= 1.17.9) + jekyll (= 3.9.3) + jekyll-avatar (= 0.7.0) + jekyll-coffeescript (= 1.1.1) + jekyll-commonmark-ghpages (= 0.4.0) + jekyll-default-layout (= 0.1.4) + jekyll-feed (= 0.15.1) + jekyll-gist (= 1.5.0) + jekyll-github-metadata (= 2.13.0) + jekyll-include-cache (= 0.2.1) + jekyll-mentions (= 1.6.0) + jekyll-optional-front-matter (= 0.3.2) + jekyll-paginate (= 1.1.0) + jekyll-readme-index (= 0.3.0) + jekyll-redirect-from (= 0.16.0) + jekyll-relative-links (= 0.6.1) + jekyll-remote-theme (= 0.4.3) + jekyll-sass-converter (= 1.5.2) + jekyll-seo-tag (= 2.8.0) + jekyll-sitemap (= 1.4.0) + jekyll-swiss (= 1.0.0) + jekyll-theme-architect (= 0.2.0) + jekyll-theme-cayman (= 0.2.0) + jekyll-theme-dinky (= 0.2.0) + jekyll-theme-hacker (= 0.2.0) + jekyll-theme-leap-day (= 0.2.0) + jekyll-theme-merlot (= 0.2.0) + jekyll-theme-midnight (= 0.2.0) + jekyll-theme-minimal (= 0.2.0) + jekyll-theme-modernist (= 0.2.0) + jekyll-theme-primer (= 0.6.0) + jekyll-theme-slate (= 0.2.0) + jekyll-theme-tactile (= 0.2.0) + jekyll-theme-time-machine (= 0.2.0) + jekyll-titles-from-headings (= 0.5.3) + jemoji (= 0.12.0) + kramdown (= 2.3.2) + kramdown-parser-gfm (= 1.1.0) + liquid (= 4.0.4) + mercenary (~> 0.3) + minima (= 2.5.1) + nokogiri (>= 1.13.6, < 2.0) + rouge (= 3.26.0) + terminal-table (~> 1.4) + github-pages-health-check (1.17.9) + addressable (~> 2.3) + dnsruby (~> 1.60) + octokit (~> 4.0) + public_suffix (>= 3.0, < 5.0) + typhoeus (~> 1.3) + github-pages-unscramble (0.1.0) + html-pipeline (2.14.3) + activesupport (>= 2) + nokogiri (>= 1.4) + http_parser.rb (0.8.0) + httpclient (2.8.3) + i18n (1.14.1) + concurrent-ruby (~> 1.0) + jekyll (3.9.3) + addressable (~> 2.4) + colorator (~> 1.0) + em-websocket (~> 0.5) + i18n (>= 0.7, < 2) + jekyll-sass-converter (~> 1.0) + jekyll-watch (~> 2.0) + kramdown (>= 1.17, < 3) + liquid (~> 4.0) + mercenary (~> 0.3.3) + pathutil (~> 0.9) + rouge (>= 1.7, < 4) + safe_yaml (~> 1.0) + jekyll-algolia (1.7.1) + algolia_html_extractor (~> 2.6) + algoliasearch (~> 1.26) + filesize (~> 0.1) + jekyll (>= 3.6, < 5.0) + json (~> 2.0) + nokogiri (~> 1.6) + progressbar (~> 1.9) + verbal_expressions (~> 0.1.5) + jekyll-avatar (0.7.0) + jekyll (>= 3.0, < 5.0) + jekyll-coffeescript (1.1.1) + coffee-script (~> 2.2) + coffee-script-source (~> 1.11.1) + jekyll-commonmark (1.4.0) + commonmarker (~> 0.22) + jekyll-commonmark-ghpages (0.4.0) + commonmarker (~> 0.23.7) + jekyll (~> 3.9.0) + jekyll-commonmark (~> 1.4.0) + rouge (>= 2.0, < 5.0) + jekyll-default-layout (0.1.4) + jekyll (~> 3.0) + jekyll-feed (0.15.1) + jekyll (>= 3.7, < 5.0) + jekyll-gist (1.5.0) + octokit (~> 4.2) + jekyll-github-metadata (2.13.0) + jekyll (>= 3.4, < 5.0) + octokit (~> 4.0, != 4.4.0) + jekyll-include-cache (0.2.1) + jekyll (>= 3.7, < 5.0) + jekyll-mentions (1.6.0) + html-pipeline (~> 2.3) + jekyll (>= 3.7, < 5.0) + jekyll-optional-front-matter (0.3.2) + jekyll (>= 3.0, < 5.0) + jekyll-paginate (1.1.0) + jekyll-readme-index (0.3.0) + jekyll (>= 3.0, < 5.0) + jekyll-redirect-from (0.16.0) + jekyll (>= 3.3, < 5.0) + jekyll-relative-links (0.6.1) + jekyll (>= 3.3, < 5.0) + jekyll-remote-theme (0.4.3) + addressable (~> 2.0) + jekyll (>= 3.5, < 5.0) + jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0) + rubyzip (>= 1.3.0, < 3.0) + jekyll-sass-converter (1.5.2) + sass (~> 3.4) + jekyll-seo-tag (2.8.0) + jekyll (>= 3.8, < 5.0) + jekyll-sitemap (1.4.0) + jekyll (>= 3.7, < 5.0) + jekyll-swiss (1.0.0) + jekyll-theme-architect (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-cayman (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-dinky (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-hacker (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-leap-day (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-merlot (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-midnight (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-minimal (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-modernist (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-primer (0.6.0) + jekyll (> 3.5, < 5.0) + jekyll-github-metadata (~> 2.9) + jekyll-seo-tag (~> 2.0) + jekyll-theme-slate (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-tactile (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-time-machine (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-titles-from-headings (0.5.3) + jekyll (>= 3.3, < 5.0) + jekyll-watch (2.2.1) + listen (~> 3.0) + jemoji (0.12.0) + gemoji (~> 3.0) + html-pipeline (~> 2.2) + jekyll (>= 3.0, < 5.0) + json (2.6.3) + kramdown (2.3.2) + rexml + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + liquid (4.0.4) + listen (3.7.1) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + mercenary (0.3.6) + minima (2.5.1) + jekyll (>= 3.5, < 5.0) + jekyll-feed (~> 0.9) + jekyll-seo-tag (~> 2.1) + minitest (5.19.0) + nokogiri (1.14.3-arm64-darwin) + racc (~> 1.4) + nokogiri (1.14.3-x86_64-linux) + racc (~> 1.4) + octokit (4.25.1) + faraday (>= 1, < 3) + sawyer (~> 0.9) + pathutil (0.16.2) + forwardable-extended (~> 2.6) + progressbar (1.11.0) + public_suffix (4.0.7) + racc (1.6.2) + rb-fsevent (0.11.2) + rb-inotify (0.10.1) + ffi (~> 1.0) + rexml (3.2.5) + rouge (3.26.0) + ruby2_keywords (0.0.5) + rubyzip (2.3.2) + safe_yaml (1.0.5) + sass (3.7.4) + sass-listen (~> 4.0.0) + sass-listen (4.0.0) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + sawyer (0.9.2) + addressable (>= 2.3.5) + faraday (>= 0.17.3, < 3) + simpleidn (0.2.1) + unf (~> 0.1.4) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + typhoeus (1.4.0) + ethon (>= 0.9.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + tzinfo-data (1.2022.7) + tzinfo (>= 1.0.0) + unf (0.1.4) + unf_ext + unf_ext (0.0.8.2) + unicode-display_width (1.8.0) + verbal_expressions (0.1.5) + webrick (1.8.1) + zeitwerk (2.6.11) + +PLATFORMS + arm64-darwin-21 + x86_64-linux + +DEPENDENCIES + activesupport (>= 4.1.11) + github-pages + github-pages-unscramble + jekyll-algolia + jekyll-feed + jekyll-gist + jekyll-include-cache + jekyll-paginate + jekyll-sitemap + jemoji + tzinfo-data + webrick + +BUNDLED WITH + 2.3.16 diff --git a/README.md b/README.md new file mode 100644 index 000000000..9f35de645 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# Ryan P. Randall's Website + +This is a static site primarily made using [Jekyll](http://jekyllrb.com/), [Markdown](http://daringfireball.net/projects/markdown/), the [Minimal Mistakes](https://github.com/mmistakes/minimal-mistakes) theme, tinkering, and patience. + +You might also encounter [Bigfoot.js](http://www.bigfootjs.com/) and [Reveal.js](http://revealjs.com/) scattered throughout this site. + +Take [a look here](http://ryan-p-randall.github.io/). + +If you're looking to make a similar website for yourself, here's a great [set of introductions & instructions to Jekyll & GitHub Pages](https://web.archive.org/web/20170415073331/http://www.trevordjones.com/jekyll). diff --git a/_sass/minimal-mistakes.scss b/_sass/minimal-mistakes.scss new file mode 100755 index 000000000..13cbeddbd --- /dev/null +++ b/_sass/minimal-mistakes.scss @@ -0,0 +1,50 @@ +/*! + * Minimal Mistakes Jekyll Theme 4.17.2 by Michael Rose + * Copyright 2013-2019 Michael Rose - mademistakes.com | @mmistakes + * Licensed under MIT (https://github.com/mmistakes/minimal-mistakes/blob/master/LICENSE) +*/ + +/* Variables */ +@import "minimal-mistakes/variables"; + +/* Mixins and functions */ +@import "minimal-mistakes/vendor/breakpoint/breakpoint"; +@include breakpoint-set("to ems", true); +@import "minimal-mistakes/vendor/magnific-popup/magnific-popup"; // Magnific Popup +@import "minimal-mistakes/vendor/susy/susy"; +@import "minimal-mistakes/mixins"; + +/* Core CSS */ +@import "minimal-mistakes/reset"; +@import "minimal-mistakes/base"; +@import "minimal-mistakes/forms"; +@import "minimal-mistakes/tables"; +@import "minimal-mistakes/animations"; + +/* Components */ +@import "minimal-mistakes/buttons"; +@import "minimal-mistakes/notices"; +@import "minimal-mistakes/masthead"; +@import "minimal-mistakes/navigation"; +@import "minimal-mistakes/footer"; +@import "minimal-mistakes/search"; +@import "minimal-mistakes/syntax"; + +/* Utility classes */ +@import "minimal-mistakes/utilities"; + +/* Layout specific */ +@import "minimal-mistakes/page"; +@import "minimal-mistakes/archive"; +@import "minimal-mistakes/sidebar"; +@import "minimal-mistakes/print"; + +/* My additions */ + +.pagination li a.disabled { + color: rgba(241,241,241,0.8); +} + +.sidebar { + opacity: 1; +} \ No newline at end of file diff --git a/_sass/vendor/bigfoot/bigfoot-mixins.scss b/_sass/vendor/bigfoot/bigfoot-mixins.scss new file mode 100644 index 000000000..60bda6dd4 --- /dev/null +++ b/_sass/vendor/bigfoot/bigfoot-mixins.scss @@ -0,0 +1,27 @@ +// ___ ___ ___ ___ +// /__/\ ___ /__/| ___ /__/\ / /\ +// | |::\ / /\ | |:| / /\ \ \:\ / /:/_ +// | |:|:\ / /:/ | |:| / /:/ \ \:\ / /:/ /\ +// __|__|:|\:\ /__/::\ __|__|:| /__/::\ _____\__\:\ / /:/ /::\ +// /__/::::| \:\\__\/\:\__/__/::::\____\__\/\:\__ /__/::::::::\/__/:/ /:/\:\ +// \ \:\~~\__\/ \ \:\/\ ~\~~\::::/ \ \:\/\\ \:\~~\~~\/\ \:\/:/~/:/ +// \ \:\ \__\::/ |~~|:|~~ \__\::/ \ \:\ ~~~ \ \::/ /:/ +// \ \:\ /__/:/ | |:| /__/:/ \ \:\ \__\/ /:/ +// \ \:\ \__\/ | |:| \__\/ \ \:\ /__/:/ +// \__\/ |__|/ \__\/ \__\/ + +@mixin print-styles { + // These styles restore the original footnote numbers and texts when the page is printed + @media not print { + .footnote-print-only { + display: none !important; + } + } + + @media print { + .bigfoot-footnote, + .bigfoot-footnote__button { + display: none !important; + } + } +} diff --git a/_sass/vendor/bigfoot/bigfoot-number.scss b/_sass/vendor/bigfoot/bigfoot-number.scss new file mode 100644 index 000000000..a0bade3ab --- /dev/null +++ b/_sass/vendor/bigfoot/bigfoot-number.scss @@ -0,0 +1,686 @@ +// bigfoot - v2.1.1 - 2015.04.04 + + +// ___ ___ ___ ___ ___ ___ +// / /\ / /\ / /\ / /\ ___ / /\ / /\ +// / /::\ / /::\ / /::\ / /::\ /__/\ / /:/_ / /::\ +// / /:/\:\ / /:/\:\ / /:/\:\ / /:/\:\ \ \:\ / /:/ /\ / /:/\:\ +// / /:/~/:// /:/ \:\ / /:/~/:// /:/ \:\ \ \:\ / /:/ /:/_ / /:/~/:/ +// /__/:/ /://__/:/ \__\:\/__/:/ /://__/:/ \__\:\ ___ \__\:\/__/:/ /:/ /\/__/:/ /:/___ +// \ \:\/:/ \ \:\ / /:/\ \:\/:/ \ \:\ / /://__/\ | |:|\ \:\/:/ /:/\ \:\/:::::/ +// \ \::/ \ \:\ /:/ \ \::/ \ \:\ /:/ \ \:\| |:| \ \::/ /:/ \ \::/~~~~ +// \ \:\ \ \:\/:/ \ \:\ \ \:\/:/ \ \:\__|:| \ \:\/:/ \ \:\ +// \ \:\ \ \::/ \ \:\ \ \::/ \__\::::/ \ \::/ \ \:\ +// \__\/ \__\/ \__\/ \__\/ ~~~~ \__\/ \__\/ +// +// These are the key variables for styling the popover. +// Just set the variable to none if you don't want that styling. + +// KEY VARIABLES +// ============================================================================= + +// STYLES +$popover-width: 22em !default; // Ideal width of the popover +$popover-max-width: 90% !default; // Best as a % to accommodate smaller viewports +$popover-max-height: 15em !default; // Maximum size of the content area +$popover-color-background: rgb(250, 250, 250) !default; // Color of the popover background +$popover-border-radius: 0.5em !default; // Radius of the corners of the popover +$popover-border: 1px solid rgb(195, 195, 195) !default; // Border of the popover/ tooltip +$popover-inactive-opacity: 0 !default; // Opacity of the popover when instantiated/ deactivating +$popover-active-opacity: 0.97 !default; // Opacity of the popover when active +$popover-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3) !default; // Sets the box shadow under the popover/ tooltip +$popover-bottom-position: auto !default; // Sets the bottom position of the popover. Use only when setting positionPopover to false in the script +$popover-left-position: auto !default; // Sets the left position of the popover. Use only when setting positionPopover to false in the script +$popover-tooltip-size: 1.3em !default; // Sets the side lengths of the tooltip +$popover-scroll-indicator-width: 0.625em !default; // The width of the scroll indicator +$popover-scroll-indicator-aspect-ratio: (15/12) !default; // The ratio of the height over the width of the scroll indicator +$popover-scroll-indicator-opacity: 0.1 !default; // The active opacity of scroll indicators +$popover-initial-transform-state: scale(0.1) translateZ(0) !default; // The inital transform state for the popover +$popover-active-transform-state: scale(1) translateZ(0) !default; // The transform state for the popover once it is fully activated + +// OPTIONAL ELEMENTS +$popover-include-tooltip: true !default; // Adds a tooltip pointing to the footnote button +$popover-include-scroll-indicator: true !default; // Adds an elipsis at the bottom of scrollable popovers +$popover-include-scrolly-fades: true !default; // Fades content in on scrollable popovers +$popover-scroll-indicator-icon: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTJweCIgaGVpZ2h0PSIxNXB4IiB2aWV3Qm94PSIwIDAgMTIgMTUiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pbllNaW4iPgogICAgPGcgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9IkFycm93IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxLjAwMDAwMCwgMS4wMDAwMDApIiBzdHJva2U9ImJsYWNrIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiPgogICAgICAgICAgICA8cGF0aCBkPSJNNSwwIEw1LDExLjUiIGlkPSJMaW5lIj48L3BhdGg+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0wLjUsNy41IEw1LjAyNzY5Mjc5LDEyLjAyNzY5MjgiIGlkPSJMaW5lIj48L3BhdGg+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik00LjUsNy41IEw5LjAyNzY5Mjc5LDEyLjAyNzY5MjgiIGlkPSJMaW5lLTIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDcuMDAwMDAwLCAxMC4wMDAwMDApIHNjYWxlKC0xLCAxKSB0cmFuc2xhdGUoLTcuMDAwMDAwLCAtMTAuMDAwMDAwKSAiPjwvcGF0aD4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPgo=") !default; + + +// OTHER VARIABLES +// ============================================================================= + +// POPOVER +$popover-margin-top: 0.1em !default; +$popover-padding-content-horizontal: 1.3em !default; +$popover-padding-content-top: 1.1em !default; +$popover-padding-content-bottom: 1.2em !default; +$popover-z-index: 10 !default; // Set the base so that it's above the other body children +$popover-initial-transform-origin: 50% 0 !default; + +// POPOVER CONTENT WRAPPER +$popover-content-color-background: $popover-color-background !default; +$popover-content-border-radius: $popover-border-radius !default; + +// OTHER POPOVER ELEMENTS +$popover-tooltip-background: $popover-color-background !default; +$popover-tooltip-radius: 0 !default; +$popover-scroll-indicator-bottom-position: 0.45em !default; +$popover-scrolly-fade-gradient-start-location: 50% !default; +$popover-scroll-indicator-padding: (($popover-padding-content-horizontal/2) - ($popover-scroll-indicator-width/2)) !default; + +// TRANSITIONS +$popover-transition-default-duration: 0.25s !default; +$popover-scroll-indicator-transition-properties: opacity !default; + +// Use none for areas you don't want to transition +$popover-transition-properties: opacity, transform !default; // no mixin to do proper prefixing of the transform, so I have to do it manually; see mixin below +$popover-scroll-indicator-transition-properties: opacity !default; +$popover-scroll-up-transition-delay: 0.4s !default; // Sets the delay for the transition of the scroll indicator when scrolling upwards +$popover-transition-default-timing-function: ease !default; + + + + + +// ___ ___ ___ +// _____ /__/\ ___ ___ / /\ /__/\ +// / /::\ \ \:\ / /\ / /\ / /::\ \ \:\ +// / /:/\:\ \ \:\ / /:/ / /:/ / /:/\:\ \ \:\ +// / /:/~/::\ ___ \ \:\ / /:/ / /:/ / /:/ \:\ _____\__\:\ +// /__/:/ /:/\:|/__/\ \__\:\ / /::\ / /::\ /__/:/ \__\:\/__/::::::::\ +// \ \:\/:/~/:/\ \:\ / /://__/:/\:\ /__/:/\:\\ \:\ / /:/\ \:\~~\~~\/ +// \ \::/ /:/ \ \:\ /:/ \__\/ \:\\__\/ \:\\ \:\ /:/ \ \:\ ~~~ +// \ \:\/:/ \ \:\/:/ \ \:\ \ \:\\ \:\/:/ \ \:\ +// \ \::/ \ \::/ \__\/ \__\/ \ \::/ \ \:\ +// \__\/ \__\/ \__\/ \__\/ +// +// These are the key variables for styling the button. +// Just set the variable to none if you don't want that styling. + +// KEY VARIABLES +// ============================================================================= + +$button-height: 0.95em !default; // The total height of the button +$button-width: auto !default; // The total button width (applies only if $button-apply-dimensions is true) +$button-inner-circle-size: 0.25em !default; // Total height/width of the ellipsis circles +$button-border-radius: 0.3em !default; // Border radius on the button itself +$button-left-margin: 0.2em !default; // Margin between the button and the text to its left +$button-right-margin: 0.1em !default; // Margin between the button and the text to its right +$button-vertical-adjust: -0.1em !default; // Pushes the buttons along the vertical axis to align it with text as desired +$button-inner-circle-left-margin: 1*$button-inner-circle-size !default; // Space between the ellipsis circles + +$button-color: rgb(110, 110, 110) !default; // Background color of the button +$button-hovered-color: $button-color !default; // Background color of the button when being hovered +$button-activating-color: $button-color !default; // Background color of the button when being clicked +$button-active-color: $button-color !default; // Background color of the button when active +$button-standard-opacity: 0.2 !default; // Opacity for when the button is just sittin' there +$button-hovered-opacity: 0.5 !default; // Opacity for when the button is being hovered over +$button-activating-opacity: $button-hovered-opacity !default; // Opacity for when the button is being clicked +$button-active-opacity: 1 !default; // Opacity for when the button is active +$button-active-style-delay: 0.1s !default; // Delay before applying .active styles; this can be used to match to the popover activation transition + +$button-inner-circle-color: white !default; // Background color of the ellipsis circle +$button-inner-circle-border: none !default; // Border of the ellipsis circle + + +// OTHER VARIABLES +// ============================================================================= + +$button-total-padding: $button-height - $button-inner-circle-size !default; +$button-per-side-padding: 0.5*$button-total-padding !default; +$button-transition-properties: background-color !default; + + + +// ----- + + +// ___ ___ ___ ___ +// /__/\ ___ /__/| ___ /__/\ / /\ +// | |::\ / /\ | |:| / /\ \ \:\ / /:/_ +// | |:|:\ / /:/ | |:| / /:/ \ \:\ / /:/ /\ +// __|__|:|\:\ /__/::\ __|__|:| /__/::\ _____\__\:\ / /:/ /::\ +// /__/::::| \:\\__\/\:\__/__/::::\____\__\/\:\__ /__/::::::::\/__/:/ /:/\:\ +// \ \:\~~\__\/ \ \:\/\ ~\~~\::::/ \ \:\/\\ \:\~~\~~\/\ \:\/:/~/:/ +// \ \:\ \__\::/ |~~|:|~~ \__\::/ \ \:\ ~~~ \ \::/ /:/ +// \ \:\ /__/:/ | |:| /__/:/ \ \:\ \__\/ /:/ +// \ \:\ \__\/ | |:| \__\/ \ \:\ /__/:/ +// \__\/ |__|/ \__\/ \__\/ + +@mixin print-styles { + // These styles restore the original footnote numbers and texts when the page is printed + @media not print { + .footnote-print-only { + display: none !important; + } + } + + @media print { + .bigfoot-footnote, + .bigfoot-footnote__button { + display: none !important; + } + } +} + + + +// ----- + + +// ___ ___ ___ +// _____ /__/\ ___ ___ / /\ /__/\ +// / /::\ \ \:\ / /\ / /\ / /::\ \ \:\ +// / /:/\:\ \ \:\ / /:/ / /:/ / /:/\:\ \ \:\ +// / /:/~/::\ ___ \ \:\ / /:/ / /:/ / /:/ \:\ _____\__\:\ +// /__/:/ /:/\:|/__/\ \__\:\ / /::\ / /::\ /__/:/ \__\:\/__/::::::::\ +// \ \:\/:/~/:/\ \:\ / /://__/:/\:\ /__/:/\:\\ \:\ / /:/\ \:\~~\~~\/ +// \ \::/ /:/ \ \:\ /:/ \__\/ \:\\__\/ \:\\ \:\ /:/ \ \:\ ~~~ +// \ \:\/:/ \ \:\/:/ \ \:\ \ \:\\ \:\/:/ \ \:\ +// \ \::/ \ \::/ \__\/ \__\/ \ \::/ \ \:\ +// \__\/ \__\/ \__\/ \__\/ + + + +//* +// The button that activates the footnote. By default, this will appear as a +// flat button that has an ellipse contained inside of it. + +// @state .is-active - The associated popover has been activated and is visible. + +// @since 2.1.0 +// @author Chris Sauve + +.bigfoot-footnote__button { + // POSITIONING + position: relative; + z-index: 5; + top: $button-vertical-adjust; + + // DISPLAY AND SIZING + box-sizing: border-box; + -moz-box-sizing: border-box;; + display: inline-block; + padding: $button-per-side-padding; + margin: 0 $button-right-margin 0 $button-left-margin; + + // BACKDROP + border: none; + border-radius: $button-border-radius; + cursor: pointer; + background-color: rgba($button-color, $button-standard-opacity); + backface-visibility: hidden; + + // TEXT + font-size: 1rem; + line-height: 0; + vertical-align: middle; + text-decoration: none; + -webkit-font-smoothing: antialiased; + + // TRANSITIONS + transition-property: $button-transition-properties; + transition-duration: $popover-transition-default-duration; + + &:hover, + &:focus { + outline: none; + background-color: rgba($button-hovered-color, $button-hovered-opacity); + } + + &:active { + background-color: rgba($button-activating-color, $button-activating-opacity); + } + + &.is-active { + background-color: rgba($button-active-color, $button-active-opacity); + transition-delay: $button-active-style-delay; + } + + // Clearfix + &:after { + content: ''; + display: table; + clear: both; + } +} + + + + + +// _____ ___ ___ +// / /::\ / /\ ___ / /\ +// / /:/\:\ / /::\ / /\ / /:/_ +// / /:/ \:\ / /:/\:\ / /:/ / /:/ /\ +// /__/:/ \__\:| / /:/ \:\ / /:/ / /:/ /::\ +// \ \:\ / /://__/:/ \__\:\ / /::\ /__/:/ /:/\:\ +// \ \:\ /:/ \ \:\ / /://__/:/\:\\ \:\/:/~/:/ +// \ \:\/:/ \ \:\ /:/ \__\/ \:\\ \::/ /:/ +// \ \::/ \ \:\/:/ \ \:\\__\/ /:/ +// \__\/ \ \::/ \__\/ /__/:/ +// \__\/ \__\/ + +//* +// Each of the three circles forming the ellipse within the button. + +// @since 2.1.0 +// @author Chris Sauve + +.bigfoot-footnote__button__circle { + // DISPLAY AND SIZING + display: inline-block; + width: $button-inner-circle-size; + height: $button-inner-circle-size; + margin-right: $button-inner-circle-left-margin; + float: left; + + // Gets rid of margin on the last circle + &:last-child { margin-right: 0; } +} + + + + + +// ___ ___ ___ ___ ___ +// / /\ / /\ /__/\ ___ / /\ ___ /__/\ +// / /:/ / /::\ \ \:\ / /\ / /::\ / /\ \ \:\ +// / /:/ / /:/\:\ \ \:\ / /:/ / /:/\:\ / /:/ \ \:\ +// / /:/ ___ / /:/ \:\ _____\__\:\ / /:/ / /:/~/::\ /__/::\ _____\__\:\ +// /__/:/ / /\/__/:/ \__\:\/__/::::::::\ / /::\ /__/:/ /:/\:\\__\/\:\__ /__/::::::::\ +// \ \:\ / /:/\ \:\ / /:/\ \:\~~\~~\//__/:/\:\\ \:\/:/__\/ \ \:\/\\ \:\~~\~~\/ +// \ \:\ /:/ \ \:\ /:/ \ \:\ ~~~ \__\/ \:\\ \::/ \__\::/ \ \:\ ~~~ +// \ \:\/:/ \ \:\/:/ \ \:\ \ \:\\ \:\ /__/:/ \ \:\ +// \ \::/ \ \::/ \ \:\ \__\/ \ \:\ \__\/ \ \:\ +// \__\/ \__\/ \__\/ \__\/ \__\/ + +//* +// The container for the button and popover. This is required so that the popover +// is guaranteed to have a relatively-positioned container, and to help with the +// positioning calculation. + +// @since 2.1.0 +// @author Chris Sauve + +.bigfoot-footnote__container { + display: inline-block; + position: relative; + text-indent: 0; +} + + + + + +// ___ ___ ___ +// / /\ / /\ ___ /__/\ ___ +// / /::\ / /::\ / /\ \ \:\ / /\ +// / /:/\:\ / /:/\:\ / /:/ \ \:\ / /:/ +// / /:/~/:// /:/~/:/ /__/::\ _____\__\:\ / /:/ +// /__/:/ /://__/:/ /:/___\__\/\:\__ /__/::::::::\ / /::\ +// \ \:\/:/ \ \:\/:::::/ \ \:\/\\ \:\~~\~~\//__/:/\:\ +// \ \::/ \ \::/~~~~ \__\::/ \ \:\ ~~~ \__\/ \:\ +// \ \:\ \ \:\ /__/:/ \ \:\ \ \:\ +// \ \:\ \ \:\ \__\/ \ \:\ \__\/ +// \__\/ \__\/ \__\/ + +@include print-styles; + + + +// ----- + + +// ___ ___ ___ ___ ___ ___ +// / /\ / /\ / /\ / /\ ___ / /\ / /\ +// / /::\ / /::\ / /::\ / /::\ /__/\ / /:/_ / /::\ +// / /:/\:\ / /:/\:\ / /:/\:\ / /:/\:\ \ \:\ / /:/ /\ / /:/\:\ +// / /:/~/:// /:/ \:\ / /:/~/:// /:/ \:\ \ \:\ / /:/ /:/_ / /:/~/:/ +// /__/:/ /://__/:/ \__\:\/__/:/ /://__/:/ \__\:\ ___ \__\:\/__/:/ /:/ /\/__/:/ /:/___ +// \ \:\/:/ \ \:\ / /:/\ \:\/:/ \ \:\ / /://__/\ | |:|\ \:\/:/ /:/\ \:\/:::::/ +// \ \::/ \ \:\ /:/ \ \::/ \ \:\ /:/ \ \:\| |:| \ \::/ /:/ \ \::/~~~~ +// \ \:\ \ \:\/:/ \ \:\ \ \:\/:/ \ \:\__|:| \ \:\/:/ \ \:\ +// \ \:\ \ \::/ \ \:\ \ \::/ \__\::::/ \ \::/ \ \:\ +// \__\/ \__\/ \__\/ \__\/ ~~~~ \__\/ \__\/ +// + + + +//* +// The popover for the footnote. This popover will be, by default, be sized and positioned +// by the script. However, many of the sizes can be established in this stylesheet and +// will be respected by the script. `max-width` will limit the width of the popover +// relative to the viewport. `width` (on `bigfoot-footnote__wrapper`) will set the +// absolute max width. Max height can be set via a `max-height` property +// on `bigfoot-footnote__content`. + +// By default, the popover has a light gray background, a shadow for some depth, +// rounded corners, and a tooltip pointing to the footnote button. + +// @state .is-active - The popover has been activated and is visible. +// @state .is-positioned-top - The popover is above the button. +// @state .is-positioned-bottom - The popover is below the button. +// @state .is-scrollable - The popover content is greater than the popover height. +// @state .is-fully-scrolled - The popover content is scrolled to the bottom. + +// @since 2.1.0 +// @author Chris Sauve + +.bigfoot-footnote { + // POSITIONING + position: absolute; + z-index: $popover-z-index; + top: 0; left: 0; + + // DISPLAY AND SIZING + display: inline-block; + box-sizing: border-box; + // Height is set in .footnote-content-wrapper + max-width: $popover-max-width; + // 1.414213... is to get the diagonal height of the tooltip using pythagorus, yo. + margin: ((1.4142135624 * $popover-tooltip-size / 2) + $button-height + $popover-margin-top) 0; + // fits the popover to the contents + + // BACKDROP + background: $popover-color-background; + opacity: $popover-inactive-opacity; + border-radius: $popover-border-radius; + border: $popover-border; + box-shadow: $popover-box-shadow; + + // TEXT + line-height: 0; + + // TRANSITIONS + transition-property: $popover-transition-properties; + transition-duration: $popover-transition-default-duration; + transition-timing-function: $popover-transition-default-timing-function; + + // TRANSFORMS + transform: $popover-initial-transform-state; + transform-origin: $popover-initial-transform-origin; + + &.is-positioned-top { + top: auto; + bottom: 0; + } + + &.is-active { + transform: $popover-active-transform-state; + opacity: $popover-active-opacity; + } + + &.is-bottom-fixed { + // POSITIONING + position: fixed; + bottom: 0; top: auto; + left: 0; right: auto; + transform: translateY(100%); + + // DISPLAY AND SIZING + width: 100%; + margin: 0; + + // BACKDROP + border-radius: 0; + opacity: 1; + border-width: 1px 0 0; + + // TRANSITIONS + transition: transform 0.3s ease; + + &.is-active { + transform: translateY(0); + } + + .bigfoot-footnote__wrapper { + margin: 0 0 0 50%; + transform: translateX(-50%); + max-width: 100%; + } + + .bigfoot-footnote__wrapper, + .bigfoot-footnote__content { + border-radius: 0; + } + + .bigfoot-footnote__tooltip { + display: none; + } + } + + &.is-scrollable { + // A scrollable indicator in the left margin of the popover. + &:after { + // CONTENT + content: ''; + + // POSITIONING + position: absolute; + bottom: $popover-scroll-indicator-padding; + left: $popover-scroll-indicator-padding; + z-index: ($popover-z-index + 4); + + // DISPLAY AND SIZING + display: block; + height: ($popover-scroll-indicator-width*$popover-scroll-indicator-aspect-ratio); + width: $popover-scroll-indicator-width; + + // BACKDROP + background-image: $popover-scroll-indicator-icon; + background-size: cover; + opacity: $popover-scroll-indicator-opacity; + transition-properties: $popover-scroll-indicator-transition-properties; + transition-duration: $popover-transition-default-duration; + transition-timing-function: $popover-transition-default-timing-function; + } + + .bigfoot-footnote__wrapper { + &:before, + &:after { + content: ''; + position: absolute; + width: 100%; + // Above the content + z-index: ($popover-z-index + 2); + left: 0; + } + + &:before { + top: -1px; + height: $popover-padding-content-top; + border-radius: $popover-border-radius $popover-border-radius 0 0; + background-image: linear-gradient(to bottom, $popover-color-background $popover-scrolly-fade-gradient-start-location, transparentize($popover-color-background, 1) 100%); + } + + &:after { + bottom: -1px; + height: $popover-padding-content-bottom; + border-radius: 0 0 $popover-border-radius $popover-border-radius; + background-image: linear-gradient(to top, $popover-color-background $popover-scrolly-fade-gradient-start-location, transparentize($popover-color-background, 1) 100%); + } + } + + ::-webkit-scrollbar { display: none; } + } + + &.is-fully-scrolled { + &:after, + &:before { + opacity: 0; + transition-delay: 0; + } + } +} + + + +//* +// Wraps around the footnote content. This is necessary in order to have an element +// above the tooltip and that can provide top and bottom indicators that there is +// additional content on scrollable popovers. + +// @since 2.1.0 +// @author Chris Sauve + +.bigfoot-footnote__wrapper { + // POSITIONING + position: relative; + // Above the outer tooltip, below the inner tooltip + z-index: ($popover-z-index + 4); + + // DISPLAY AND SIZING + width: $popover-width; + display: inline-block; + box-sizing: inherit; + overflow: hidden; + margin: 0; + + // BACKDROP + background-color: $popover-color-background; + border-radius: $popover-border-radius; + + // TEXT + line-height: 0; +} + + + +//* +// Contains the actual footnote content. There is very little prescription here +// on the footnote content itself, except for removing and top margin on the first +// element and bottom margin on the last child. + +// @since 2.1.0 +// @author Chris Sauve + +.bigfoot-footnote__content { + // POSITIONING + position: relative; + z-index: ($popover-z-index - 2); // Below fading bars + + // DISPLAY AND SIZING + display: inline-block; + max-height: $popover-max-height; + padding: $popover-padding-content-top $popover-padding-content-horizontal $popover-padding-content-bottom; + box-sizing: inherit; + overflow: auto; + -webkit-overflow-scrolling: touch; + + // BACKDROP + background: $popover-content-color-background; + border-radius: $popover-content-border-radius; + + // TEXT + -webkit-font-smoothing: subpixel-antialiased; + line-height: normal; + + // INTERIOR ELEMENTS + img { max-width: 100%; } + *:last-child { margin-bottom: 0 !important; } + *:first-child { margin-top: 0 !important; } +} + + + +//* +// A triangular shape pointing towards the footnote button. + +// @since 2.1.0 +// @author Chris Sauve + +.bigfoot-footnote__tooltip { + // POSITIONING + position: absolute; + // Above the footnote-main-wrapper and the outer tooltip + z-index: ($popover-z-index + 2); + + // DISPLAY AND SIZING + box-sizing: border-box; + margin-left: (-0.5 * $popover-tooltip-size); + // Smaller by one border-width's worth + width: $popover-tooltip-size; + height: $popover-tooltip-size; + transform: rotate(45deg); + + // BACKDROP + background: $popover-tooltip-background; + border: $popover-border; + box-shadow: $popover-box-shadow; + border-top-left-radius: $popover-tooltip-radius; + + .is-positioned-bottom & { + top: (-0.5 * $popover-tooltip-size); + } + + .is-positioned-top & { + bottom: (-0.5 * $popover-tooltip-size); + } +} + + + +// ----- + + +// ___ ___ ___ ___ ___ +// /__/\ /__/\ /__/\ _____ / /\ / /\ +// \ \:\ \ \:\ | |::\ / /::\ / /:/_ / /::\ +// \ \:\ \ \:\ | |:|:\ / /:/\:\ / /:/ /\ / /:/\:\ +// _____\__\:\ ___ \ \:\ __|__|:|\:\ / /:/~/::\ / /:/ /:/_ / /:/~/:/ +// /__/::::::::\/__/\ \__\:\/__/::::| \:\/__/:/ /:/\:|/__/:/ /:/ /\/__/:/ /:/___ +// \ \:\~~\~~\/\ \:\ / /:/\ \:\~~\__\/\ \:\/:/~/:/\ \:\/:/ /:/\ \:\/:::::/ +// \ \:\ ~~~ \ \:\ /:/ \ \:\ \ \::/ /:/ \ \::/ /:/ \ \::/~~~~ +// \ \:\ \ \:\/:/ \ \:\ \ \:\/:/ \ \:\/:/ \ \:\ +// \ \:\ \ \::/ \ \:\ \ \::/ \ \::/ \ \:\ +// \__\/ \__\/ \__\/ \__\/ \__\/ \__\/ + + + +//* +// A button that has no ellipse, but instead shows the footnote's number on the +// page. Note that the number will be reset to 1 depending on the selector passed +// to bigfoot's `numberResetSelector` option. + +// @since 2.1.0 +// @author Chris Sauve + +.bigfoot-footnote__button { + position: relative; + height: $button-height; + width: 1.5em; + border-radius: $button-height/2; + + &:after { + // CONTENT + content: attr(data-footnote-number); + + // POSITION + position: absolute; + top: 50%; left: 50%; + transform: translate(-50%, -50%); + + // DISPLAY AND SIZING + display: block; + + // TEXT + font-size: $button-height*0.6; + font-weight: bold; + color: mix(#fff, $link-color, 30%); // #ff6600; +// originally: color: rgba($button-color, 0.5); + + // TRANSITIONS + transition: color $popover-transition-default-duration $popover-transition-default-timing-function; + } + + &:hover, + &.is-active { + &:after { + color: white; + } + } +} + +.bigfoot-footnote__button__circle { + display: none; +} diff --git a/_sass/vendor/bigfoot/bigfoot-popover.scss b/_sass/vendor/bigfoot/bigfoot-popover.scss new file mode 100644 index 000000000..df92609b4 --- /dev/null +++ b/_sass/vendor/bigfoot/bigfoot-popover.scss @@ -0,0 +1,286 @@ +// ___ ___ ___ ___ ___ ___ +// / /\ / /\ / /\ / /\ ___ / /\ / /\ +// / /::\ / /::\ / /::\ / /::\ /__/\ / /:/_ / /::\ +// / /:/\:\ / /:/\:\ / /:/\:\ / /:/\:\ \ \:\ / /:/ /\ / /:/\:\ +// / /:/~/:// /:/ \:\ / /:/~/:// /:/ \:\ \ \:\ / /:/ /:/_ / /:/~/:/ +// /__/:/ /://__/:/ \__\:\/__/:/ /://__/:/ \__\:\ ___ \__\:\/__/:/ /:/ /\/__/:/ /:/___ +// \ \:\/:/ \ \:\ / /:/\ \:\/:/ \ \:\ / /://__/\ | |:|\ \:\/:/ /:/\ \:\/:::::/ +// \ \::/ \ \:\ /:/ \ \::/ \ \:\ /:/ \ \:\| |:| \ \::/ /:/ \ \::/~~~~ +// \ \:\ \ \:\/:/ \ \:\ \ \:\/:/ \ \:\__|:| \ \:\/:/ \ \:\ +// \ \:\ \ \::/ \ \:\ \ \::/ \__\::::/ \ \::/ \ \:\ +// \__\/ \__\/ \__\/ \__\/ ~~~~ \__\/ \__\/ +// + + + +//* +// The popover for the footnote. This popover will be, by default, be sized and positioned +// by the script. However, many of the sizes can be established in this stylesheet and +// will be respected by the script. `max-width` will limit the width of the popover +// relative to the viewport. `width` (on `bigfoot-footnote__wrapper`) will set the +// absolute max width. Max height can be set via a `max-height` property +// on `bigfoot-footnote__content`. + +// By default, the popover has a light gray background, a shadow for some depth, +// rounded corners, and a tooltip pointing to the footnote button. + +// @state .is-active - The popover has been activated and is visible. +// @state .is-positioned-top - The popover is above the button. +// @state .is-positioned-bottom - The popover is below the button. +// @state .is-scrollable - The popover content is greater than the popover height. +// @state .is-fully-scrolled - The popover content is scrolled to the bottom. + +// @since 2.1.0 +// @author Chris Sauve + +.bigfoot-footnote { + // POSITIONING + position: absolute; + z-index: $popover-z-index; + top: 0; left: 0; + + // DISPLAY AND SIZING + display: inline-block; + box-sizing: border-box; + // Height is set in .footnote-content-wrapper + max-width: $popover-max-width; + // 1.414213... is to get the diagonal height of the tooltip using pythagorus, yo. + margin: ((1.4142135624 * $popover-tooltip-size / 2) + $button-height + $popover-margin-top) 0; + // fits the popover to the contents + + // BACKDROP + background: $popover-color-background; + opacity: $popover-inactive-opacity; + border-radius: $popover-border-radius; + border: $popover-border; + box-shadow: $popover-box-shadow; + + // TEXT + line-height: 0; + + // TRANSITIONS + transition-property: $popover-transition-properties; + transition-duration: $popover-transition-default-duration; + transition-timing-function: $popover-transition-default-timing-function; + + // TRANSFORMS + transform: $popover-initial-transform-state; + transform-origin: $popover-initial-transform-origin; + + &.is-positioned-top { + top: auto; + bottom: 0; + } + + &.is-active { + transform: $popover-active-transform-state; + opacity: $popover-active-opacity; + } + + &.is-bottom-fixed { + // POSITIONING + position: fixed; + bottom: 0; top: auto; + left: 0; right: auto; + transform: translateY(100%); + + // DISPLAY AND SIZING + width: 100%; + margin: 0; + + // BACKDROP + border-radius: 0; + opacity: 1; + border-width: 1px 0 0; + + // TRANSITIONS + transition: transform 0.3s ease; + + &.is-active { + transform: translateY(0); + } + + .bigfoot-footnote__wrapper { + margin: 0 0 0 50%; + transform: translateX(-50%); + max-width: 100%; + } + + .bigfoot-footnote__wrapper, + .bigfoot-footnote__content { + border-radius: 0; + } + + .bigfoot-footnote__tooltip { + display: none; + } + } + + &.is-scrollable { + // A scrollable indicator in the left margin of the popover. + &:after { + // CONTENT + content: ''; + + // POSITIONING + position: absolute; + bottom: $popover-scroll-indicator-padding; + left: $popover-scroll-indicator-padding; + z-index: ($popover-z-index + 4); + + // DISPLAY AND SIZING + display: block; + height: ($popover-scroll-indicator-width*$popover-scroll-indicator-aspect-ratio); + width: $popover-scroll-indicator-width; + + // BACKDROP + background-image: $popover-scroll-indicator-icon; + background-size: cover; + opacity: $popover-scroll-indicator-opacity; + transition-properties: $popover-scroll-indicator-transition-properties; + transition-duration: $popover-transition-default-duration; + transition-timing-function: $popover-transition-default-timing-function; + } + + .bigfoot-footnote__wrapper { + &:before, + &:after { + content: ''; + position: absolute; + width: 100%; + // Above the content + z-index: ($popover-z-index + 2); + left: 0; + } + + &:before { + top: -1px; + height: $popover-padding-content-top; + border-radius: $popover-border-radius $popover-border-radius 0 0; + background-image: linear-gradient(to bottom, $popover-color-background $popover-scrolly-fade-gradient-start-location, transparentize($popover-color-background, 1) 100%); + } + + &:after { + bottom: -1px; + height: $popover-padding-content-bottom; + border-radius: 0 0 $popover-border-radius $popover-border-radius; + background-image: linear-gradient(to top, $popover-color-background $popover-scrolly-fade-gradient-start-location, transparentize($popover-color-background, 1) 100%); + } + } + + ::-webkit-scrollbar { display: none; } + } + + &.is-fully-scrolled { + &:after, + &:before { + opacity: 0; + transition-delay: 0; + } + } +} + + + +//* +// Wraps around the footnote content. This is necessary in order to have an element +// above the tooltip and that can provide top and bottom indicators that there is +// additional content on scrollable popovers. + +// @since 2.1.0 +// @author Chris Sauve + +.bigfoot-footnote__wrapper { + // POSITIONING + position: relative; + // Above the outer tooltip, below the inner tooltip + z-index: ($popover-z-index + 4); + + // DISPLAY AND SIZING + width: $popover-width; + display: inline-block; + box-sizing: inherit; + overflow: hidden; + margin: 0; + + // BACKDROP + background-color: $popover-color-background; + border-radius: $popover-border-radius; + + // TEXT + line-height: 0; +} + + + +//* +// Contains the actual footnote content. There is very little prescription here +// on the footnote content itself, except for removing and top margin on the first +// element and bottom margin on the last child. + +// @since 2.1.0 +// @author Chris Sauve + +.bigfoot-footnote__content { + // POSITIONING + position: relative; + z-index: ($popover-z-index - 2); // Below fading bars + + // DISPLAY AND SIZING + display: inline-block; + max-height: $popover-max-height; + padding: $popover-padding-content-top $popover-padding-content-horizontal $popover-padding-content-bottom; + box-sizing: inherit; + overflow: auto; + -webkit-overflow-scrolling: touch; + + // BACKDROP + background: $popover-content-color-background; + border-radius: $popover-content-border-radius; + + // TEXT + -webkit-font-smoothing: subpixel-antialiased; + line-height: normal; + + // INTERIOR ELEMENTS + img { max-width: 100%; } + *:last-child { margin-bottom: 0 !important; } + *:first-child { margin-top: 0 !important; } +} + + + +//* +// A triangular shape pointing towards the footnote button. + +// @since 2.1.0 +// @author Chris Sauve + +.bigfoot-footnote__tooltip { + // POSITIONING + position: absolute; + // Above the footnote-main-wrapper and the outer tooltip + z-index: ($popover-z-index + 2); + + // DISPLAY AND SIZING + box-sizing: border-box; + margin-left: (-0.5 * $popover-tooltip-size); + // Smaller by one border-width's worth + width: $popover-tooltip-size; + height: $popover-tooltip-size; + transform: rotate(45deg); + + // BACKDROP + background: $popover-tooltip-background; + border: $popover-border; + box-shadow: $popover-box-shadow; + border-top-left-radius: $popover-tooltip-radius; + + .is-positioned-bottom & { + top: (-0.5 * $popover-tooltip-size); + } + + .is-positioned-top & { + bottom: (-0.5 * $popover-tooltip-size); + } +} diff --git a/_sass/vendor/bigfoot/bigfoot-variables.scss b/_sass/vendor/bigfoot/bigfoot-variables.scss new file mode 100644 index 000000000..99dc64cfc --- /dev/null +++ b/_sass/vendor/bigfoot/bigfoot-variables.scss @@ -0,0 +1,127 @@ +// ___ ___ ___ ___ ___ ___ +// / /\ / /\ / /\ / /\ ___ / /\ / /\ +// / /::\ / /::\ / /::\ / /::\ /__/\ / /:/_ / /::\ +// / /:/\:\ / /:/\:\ / /:/\:\ / /:/\:\ \ \:\ / /:/ /\ / /:/\:\ +// / /:/~/:// /:/ \:\ / /:/~/:// /:/ \:\ \ \:\ / /:/ /:/_ / /:/~/:/ +// /__/:/ /://__/:/ \__\:\/__/:/ /://__/:/ \__\:\ ___ \__\:\/__/:/ /:/ /\/__/:/ /:/___ +// \ \:\/:/ \ \:\ / /:/\ \:\/:/ \ \:\ / /://__/\ | |:|\ \:\/:/ /:/\ \:\/:::::/ +// \ \::/ \ \:\ /:/ \ \::/ \ \:\ /:/ \ \:\| |:| \ \::/ /:/ \ \::/~~~~ +// \ \:\ \ \:\/:/ \ \:\ \ \:\/:/ \ \:\__|:| \ \:\/:/ \ \:\ +// \ \:\ \ \::/ \ \:\ \ \::/ \__\::::/ \ \::/ \ \:\ +// \__\/ \__\/ \__\/ \__\/ ~~~~ \__\/ \__\/ +// +// These are the key variables for styling the popover. +// Just set the variable to none if you don't want that styling. + +// KEY VARIABLES +// ============================================================================= + +// STYLES +$popover-width: 35em; // Ideal width of the popover +$popover-max-width: 90% !default; // Best as a % to accommodate smaller viewports +$popover-max-height: 20em; // Maximum size of the content area +$popover-color-background: mix(#00b386, #252a34, 30%) !default; // Color of the popover background +$popover-border-radius: 0.5em !default; // Radius of the corners of the popover +$popover-border: 1px solid rgb(195, 195, 195) !default; // Border of the popover/ tooltip +$popover-inactive-opacity: 0 !default; // Opacity of the popover when instantiated/ deactivating +$popover-active-opacity: 0.99 !default; // Opacity of the popover when active +$popover-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3) !default; // Sets the box shadow under the popover/ tooltip +$popover-bottom-position: auto !default; // Sets the bottom position of the popover. Use only when setting positionPopover to false in the script +$popover-left-position: auto !default; // Sets the left position of the popover. Use only when setting positionPopover to false in the script +$popover-tooltip-size: 1.3em !default; // Sets the side lengths of the tooltip +$popover-scroll-indicator-width: 0.625em !default; // The width of the scroll indicator +$popover-scroll-indicator-aspect-ratio: (15/12) !default; // The ratio of the height over the width of the scroll indicator +$popover-scroll-indicator-opacity: 0.1 !default; // The active opacity of scroll indicators +$popover-initial-transform-state: scale(0.1) translateZ(0) !default; // The inital transform state for the popover +$popover-active-transform-state: scale(1) translateZ(0) !default; // The transform state for the popover once it is fully activated + +// OPTIONAL ELEMENTS +$popover-include-tooltip: true !default; // Adds a tooltip pointing to the footnote button +$popover-include-scroll-indicator: true !default; // Adds an elipsis at the bottom of scrollable popovers +$popover-include-scrolly-fades: true !default; // Fades content in on scrollable popovers +$popover-scroll-indicator-icon: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTJweCIgaGVpZ2h0PSIxNXB4IiB2aWV3Qm94PSIwIDAgMTIgMTUiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pbllNaW4iPgogICAgPGcgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9IkFycm93IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxLjAwMDAwMCwgMS4wMDAwMDApIiBzdHJva2U9ImJsYWNrIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiPgogICAgICAgICAgICA8cGF0aCBkPSJNNSwwIEw1LDExLjUiIGlkPSJMaW5lIj48L3BhdGg+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0wLjUsNy41IEw1LjAyNzY5Mjc5LDEyLjAyNzY5MjgiIGlkPSJMaW5lIj48L3BhdGg+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik00LjUsNy41IEw5LjAyNzY5Mjc5LDEyLjAyNzY5MjgiIGlkPSJMaW5lLTIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDcuMDAwMDAwLCAxMC4wMDAwMDApIHNjYWxlKC0xLCAxKSB0cmFuc2xhdGUoLTcuMDAwMDAwLCAtMTAuMDAwMDAwKSAiPjwvcGF0aD4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPgo=") !default; + + +// OTHER VARIABLES +// ============================================================================= + +// POPOVER +$popover-margin-top: 0.1em !default; +$popover-padding-content-horizontal: 1.3em !default; +$popover-padding-content-top: 1.1em !default; +$popover-padding-content-bottom: 1.2em !default; +$popover-z-index: 10 !default; // Set the base so that it's above the other body children +$popover-initial-transform-origin: 50% 0 !default; + +// POPOVER CONTENT WRAPPER +$popover-content-color-background: $popover-color-background !default; +$popover-content-border-radius: $popover-border-radius !default; + +// OTHER POPOVER ELEMENTS +$popover-tooltip-background: $popover-color-background !default; +$popover-tooltip-radius: 0 !default; +$popover-scroll-indicator-bottom-position: 0.45em !default; +$popover-scrolly-fade-gradient-start-location: 50% !default; +$popover-scroll-indicator-padding: (($popover-padding-content-horizontal/2) - ($popover-scroll-indicator-width/2)) !default; + +// TRANSITIONS +$popover-transition-default-duration: 0.25s !default; +$popover-scroll-indicator-transition-properties: opacity !default; + +// Use none for areas you don't want to transition +$popover-transition-properties: opacity, transform !default; // no mixin to do proper prefixing of the transform, so I have to do it manually; see mixin below +$popover-scroll-indicator-transition-properties: opacity !default; +$popover-scroll-up-transition-delay: 0.4s !default; // Sets the delay for the transition of the scroll indicator when scrolling upwards +$popover-transition-default-timing-function: ease !default; + + + + + +// ___ ___ ___ +// _____ /__/\ ___ ___ / /\ /__/\ +// / /::\ \ \:\ / /\ / /\ / /::\ \ \:\ +// / /:/\:\ \ \:\ / /:/ / /:/ / /:/\:\ \ \:\ +// / /:/~/::\ ___ \ \:\ / /:/ / /:/ / /:/ \:\ _____\__\:\ +// /__/:/ /:/\:|/__/\ \__\:\ / /::\ / /::\ /__/:/ \__\:\/__/::::::::\ +// \ \:\/:/~/:/\ \:\ / /://__/:/\:\ /__/:/\:\\ \:\ / /:/\ \:\~~\~~\/ +// \ \::/ /:/ \ \:\ /:/ \__\/ \:\\__\/ \:\\ \:\ /:/ \ \:\ ~~~ +// \ \:\/:/ \ \:\/:/ \ \:\ \ \:\\ \:\/:/ \ \:\ +// \ \::/ \ \::/ \__\/ \__\/ \ \::/ \ \:\ +// \__\/ \__\/ \__\/ \__\/ +// +// These are the key variables for styling the button. +// Just set the variable to none if you don't want that styling. + +// KEY VARIABLES +// ============================================================================= + +$button-height: 0.95em !default; // The total height of the button +$button-width: auto !default; // The total button width (applies only if $button-apply-dimensions is true) +$button-inner-circle-size: 0.25em !default; // Total height/width of the ellipsis circles +$button-border-radius: 0.3em !default; // Border radius on the button itself +$button-left-margin: 0.2em !default; // Margin between the button and the text to its left +$button-right-margin: 0.1em !default; // Margin between the button and the text to its right +$button-vertical-adjust: -0.1em !default; // Pushes the buttons along the vertical axis to align it with text as desired +$button-inner-circle-left-margin: 1*$button-inner-circle-size !default; // Space between the ellipsis circles + +$button-color: #00b386 !default; // Background color of the button +$button-hovered-color: $button-color !default; // Background color of the button when being hovered +$button-activating-color: $button-color !default; // Background color of the button when being clicked +$button-active-color: $button-color !default; // Background color of the button when active +$button-standard-opacity: 0.2 !default; // Opacity for when the button is just sittin' there +$button-hovered-opacity: 0.5 !default; // Opacity for when the button is being hovered over +$button-activating-opacity: $button-hovered-opacity !default; // Opacity for when the button is being clicked +$button-active-opacity: 1 !default; // Opacity for when the button is active +$button-active-style-delay: 0.1s !default; // Delay before applying .active styles; this can be used to match to the popover activation transition + +$button-inner-circle-color: white !default; // Background color of the ellipsis circle +$button-inner-circle-border: none !default; // Border of the ellipsis circle + + +// OTHER VARIABLES +// ============================================================================= + +$button-total-padding: $button-height - $button-inner-circle-size !default; +$button-per-side-padding: 0.5*$button-total-padding !default; +$button-transition-properties: background-color !default; diff --git a/about/index.html b/about/index.html new file mode 100644 index 000000000..b0c08daa6 --- /dev/null +++ b/about/index.html @@ -0,0 +1,460 @@ + + + + + + +About — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

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

As an Instructional Designer at Idaho State University, I work to help faculty design engaging, clear, and accessible online courses that improve outcomes for every learner. I'm enthusiastic about open educational resources (OERs) and open pedagogical approaches.

+ +

I'm also a student in Idaho State University's Ph.D. in English and the Teaching of English program, which emphasizes pedagogy more than most English literature programs. I serve as the Web Editor for In the Library with the Lead Pipe, an open access, open peer reviewed library journal.

+ +

In my previous role as the Instruction Coordinator and Faculty Outreach Librarian for the College of Western Idaho, I worked with students, other librarians, faculty, and staff to promote critical information literacy and library use.

+ +

Prior to librarianship, I earned an MA in English from the University of California, Riverside and an MA in Visual and Cultural Studies from the University of Rochester. While a graduate student, then as an adjunct, I taught what librarians call information literacy skills as the instructor for many first-year writing seminar courses and lower-division American Studies and Film/Media courses. I was also a college writing tutor for undergraduate and graduate students. The path of librarianship took me to IU Bloomington's MLS program, where my favorite courses emphasized critical information literacy, humanities subject librarianship, and digital humanities.

+ +

Outside of that more clearly academic stuff, I've hosted a college radio show on KUCR & WRUR, been in a band or two, and learned from participation and collective study in various do-it-ourselves communities. If you're looking for communities related to librarianship, you might start by checking out #critlib, The Librarian Parlor, and Hack Library School, each of which I often look to for insights.

+ +

CV

+ +

If all of this somehow leaves your curiosity unsated, here's my CV.

+ +

Other Pages

+ + + + +

Here’s a few pages of recommended reading I made a while ago. I should update these sometime!

+ + + + +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/acwrimo2023.html b/acwrimo2023.html new file mode 100644 index 000000000..78bdf0b1f --- /dev/null +++ b/acwrimo2023.html @@ -0,0 +1,661 @@ + + + + + + +AcWriMo2023 — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + + + +

As I recently mentioned on Mastodon, I’m going to try doing Academic Writing Month (aka “AcWriMo”; a fellow traveler of National Novel Writing Month, or “NaNoWriMo”) this year. Here I’m detailing my approach—I’ll likely also update this with my progress throughout the experiment.

+ +

La Lucha Continúa

+ +

My most consistent writing challenge has always been that writing anything longer than a blog post involves a noticeable state shift. I move—sometimes with effort, sometimes all-too-effortlessly—from mild-mannered riotnrrrd mode to superhuman hyperfocus mode, and occasionally veer into full-on ADHD lasereyes goblin mode.

+ +

This routinely produces good class & conference papers, but isn’t exactly compatible with what one might call responsible adulting.

+ +

So the crux of my dilemma: how to flip my brain into writing mode in sustainable ways that are in fact compatible with responsible adulting?

+ +

AcWriMo2023 Piece

+ +

Here are this year’s AcWriMo experiment parameters, written up somewhat as a Fluxus piece:

+ +
    +
  1. Aspire to get into the “writing headspace” for 30 minutes to an hour every other day, i.e. Mon or Tue, Wed or Thu, Fri or Sat., through November 2023.
  2. +
  3. Track the attempts. Probably share the progress & results.
  4. +
  5. “Writing headspace” here ≅ “successfully opened up my writing app and/or successfully annotated readings in one of my two reading apps.”
  6. +
+ +

As you can see, this is taking a process-based approach, not a product-based one. The aim is to see how much I can make a habit of writing in rally mode (i.e. sustained movement) rather than sprinting mode.

+ +

To provide more structure and internal support, I’ve made myself a set of tasks, using Obsidian’s Tasks plugin. Whatever stands a good chance of supporting beneficial progress, right?

+ +

Obsidian & Tasks Details

+ +

While I haven’t yet written a post or note about the Tasks plugin specifically, it’s essentially what has drawn me from Dendron to Obsidian. So here I’ll detail how I’m using Tasks to help out with AcWriMo2023, in case you’re the sort of person who appreciates worked examples. If you’re also an Obsidian user, maybe it’ll be a useful example of how you might approach projects & to-dos, using the Tasks plugin?

+ +

Here’s a link to the project tracking file I’ve made for this month’s challenge. Please adapt it to your own use as you’d like! (Here’s a link direct to the file’s raw view, if you just want to copy & paste it from your browser without seeing all the GitHub interface.)

+ +

A few important use/configuration notes:

+
    +
  • I use #tt as a global filter for Tasks. This tells the plugin not to track every single line that starts with a - [ ] checkbox, but only pay attention to the ones that start with - [ ] #tt. I’ll explain my reasons further in that eventual note, but for now, you’ll likely want to find & delete all of those tags, or find & replace them all with your own global filter if you use one.
  • +
  • I have #td/writing as an additional tag on each of these tasks. Using this sort of tag lets me use #td as a tag for all my “todo” tasks, then use the /whatever content to create subsets to display anywhere I want to have a Tasks query. Again, I’ll eventually explain this further; for now, I’m just giving any potential users of this a heads up.
  • +
  • I’ve also included the due dates for my own purposes. Again, you’ll want to change those for your own scenario. I’m just sharing all this, both to document it for Future Me and to help provide potential structures for anyone else who wants to give AcWriMo a go, last-minute.
  • +
  • There’s a Tasks query included in the file, under the Tasks View heading. This will display all the tasks on this very file, putting them in a dynamic pane that lets you change dates and interact with things more handily than you can with the Markdown / text view alone.
  • +
  • I feel like way too many people approach Obsidian as though there’s a single “correct way” to use it for tasks or projects. If you’ve read this far—and especially if you’re actually considering using my file—please approach it just as a springboard for your own experimentation. What I think might work for me, right now, isn’t guaranteed to work for me—let alone for you! I’d love it if you let me know that you found it handy or inspiring, of course.
  • +
+ +

Good luck finding what might work for you!

+ + + + + +
+ + + + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/all-hail-cloud-storage.html b/all-hail-cloud-storage.html new file mode 100644 index 000000000..10681a0c9 --- /dev/null +++ b/all-hail-cloud-storage.html @@ -0,0 +1,644 @@ + + + + + + +All Hail Cloud Storage — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + +

I wrote for Hack Library School about why & how I use Dropbox.

+ +

What I didn’t include were particular recommendations for other programs that integrate nicely with Dropbox. Perhaps it’s my college dj training that makes me super hesitant to encourage people to buy a particular program or product when I’m in a more public forum?

+ +

In any case, this is my own space, so here are the programs that I have linked to Dropbox that I use almost daily. None of these are affiliate links, I just think highly of them:

+ +
    +
  • nvALT A free program from Brett Terpstra that stores any number of text files. Using a search bar as the file-picking interface takes a bit of getting used to, but the program’s profoundly useful as a place to store ideas for the future. Just start using breadcrumbs that can help you recall the terms you’ve used—things like adding multiple “q” characters in a row for things of increasing importance, for instance. Michael Schechter shows you which settings to change in order to save your files individually rather than as a single database.
  • +
  • Editorial Ole Moritz’s program for iOS lets you work in plain text files and understands Markdown, TaskPaper, and Fountain formatting. It also has templates, automation, and Python scripting, so it’s ridiculously customizable and extendable.
  • +
+ + + + + +
+ + + + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/android-chrome-192x192.png b/android-chrome-192x192.png new file mode 100644 index 000000000..562a2ca2e Binary files /dev/null and b/android-chrome-192x192.png differ diff --git a/android-chrome-512x512.png b/android-chrome-512x512.png new file mode 100644 index 000000000..38b38a99e Binary files /dev/null and b/android-chrome-512x512.png differ diff --git a/apple-touch-icon.png b/apple-touch-icon.png new file mode 100644 index 000000000..828351d91 Binary files /dev/null and b/apple-touch-icon.png differ diff --git a/assets/css/academicons.css b/assets/css/academicons.css new file mode 100755 index 000000000..db9ec52d2 --- /dev/null +++ b/assets/css/academicons.css @@ -0,0 +1,369 @@ +/* + * Academicons 1.8.6 by James Walsh (https://github.com/jpswalsh) and Katja Bercic (https://github.com/katjabercic) + * Fonts generated using the IcoMoon app - http://icomoon.io/app + * Square icons designed to be used alongside Font Awesome square icons - https://fortawesome.github.io/Font-Awesome/ + * Licenses - Font: SIL OFL 1.1, CSS: MIT License + */ +@font-face { + font-family: 'Academicons'; + src:url('../fonts/academicons.eot?v=1.8.6'); + src:url('../fonts/academicons.eot?v=1.8.6') format('embedded-opentype'), + url('../fonts/academicons.ttf?v=1.8.6') format('truetype'), + url('../fonts/academicons.woff?v=1.8.6') format('woff'), + url('../fonts/academicons.svg?v=1.8.6#academicons') format('svg'); + font-weight: normal; + font-style: normal; +} +.ai { + display:inline-block; + font:normal normal normal 14px/1 Academicons; + font-size:inherit; + text-rendering:auto; + -webkit-font-smoothing:antialiased; + -moz-osx-font-smoothing:grayscale; +} +.ai-academia:before { + content: "\e9af"; +} +.ai-academia-square:before { + content: "\e93d"; +} +.ai-acclaim:before { + content: "\e92e"; +} +.ai-acclaim-square:before { + content: "\e93a"; +} +.ai-acm:before { + content: "\e93c"; +} +.ai-acm-square:before { + content: "\e95d"; +} +.ai-acmdl:before { + content: "\e96a"; +} +.ai-acmdl-square:before { + content: "\e9d3"; +} +.ai-ads:before { + content: "\e9cb"; +} +.ai-ads-square:before { + content: "\e94a"; +} +.ai-arxiv:before { + content: "\e974"; +} +.ai-arxiv-square:before { + content: "\e9a6"; +} +.ai-biorxiv:before { + content: "\e9a2"; +} +.ai-biorxiv-square:before { + content: "\e98b"; +} +.ai-ceur:before { + content: "\e96d"; +} +.ai-ceur-square:before { + content: "\e92f"; +} +.ai-coursera:before { + content: "\e95f"; +} +.ai-coursera-square:before { + content: "\e97f"; +} +.ai-cv:before { + content: "\e9a5"; +} +.ai-cv-square:before { + content: "\e90a"; +} +.ai-dataverse:before { + content: "\e9f7"; +} +.ai-dataverse-square:before { + content: "\e9e4"; +} +.ai-dblp:before { + content: "\e94f"; +} +.ai-dblp-square:before { + content: "\e93f"; +} +.ai-depsy:before { + content: "\e97a"; +} +.ai-depsy-square:before { + content: "\e94b"; +} +.ai-doi:before { + content: "\e97e"; +} +.ai-doi-square:before { + content: "\e98f"; +} +.ai-dryad:before { + content: "\e97c"; +} +.ai-dryad-square:before { + content: "\e98c"; +} +.ai-figshare:before { + content: "\e981"; +} +.ai-figshare-square:before { + content: "\e9e7"; +} +.ai-google-scholar:before { + content: "\e9d4"; +} +.ai-google-scholar-square:before { + content: "\e9f9"; +} +.ai-ideas-repec:before { + content: "\e9ed"; +} +.ai-ideas-repec-square:before { + content: "\e9f8"; +} +.ai-ieee:before { + content: "\e929"; +} +.ai-ieee-square:before { + content: "\e9b9"; +} +.ai-impactstory:before { + content: "\e9cf"; +} +.ai-impactstory-square:before { + content: "\e9aa"; +} +.ai-inspire:before { + content: "\e9e9"; +} +.ai-inspire-square:before { + content: "\e9fe"; +} +.ai-lattes:before { + content: "\e9b3"; +} +.ai-lattes-square:before { + content: "\e99c"; +} +.ai-mathoverflow:before { + content: "\e9f6"; +} +.ai-mathoverflow-square:before { + content: "\e97b"; +} +.ai-mendeley:before { + content: "\e9f0"; +} +.ai-mendeley-square:before { + content: "\e9f3"; +} +.ai-open-access:before { + content: "\e939"; +} +.ai-open-access-square:before { + content: "\e9f4"; +} +.ai-orcid:before { + content: "\e9d9"; +} +.ai-orcid-square:before { + content: "\e9c3"; +} +.ai-osf:before { + content: "\e9ef"; +} +.ai-osf-square:before { + content: "\e931"; +} +.ai-overleaf:before { + content: "\e914"; +} +.ai-overleaf-square:before { + content: "\e98d"; +} +.ai-philpapers:before { + content: "\e98a"; +} +.ai-philpapers-square:before { + content: "\e96f"; +} +.ai-piazza:before { + content: "\e99a"; +} +.ai-piazza-square:before { + content: "\e90c"; +} +.ai-publons:before { + content: "\e937"; +} +.ai-publons-square:before { + content: "\e94e"; +} +.ai-pubmed:before { + content: "\e99f"; +} +.ai-pubmed-square:before { + content: "\e97d"; +} +.ai-researcherid:before { + content: "\e91a"; +} +.ai-researcherid-square:before { + content: "\e95c"; +} +.ai-researchgate:before { + content: "\e95e"; +} +.ai-researchgate-square:before { + content: "\e99e"; +} +.ai-scirate:before { + content: "\e98e"; +} +.ai-scirate-square:before { + content: "\e99d"; +} +.ai-semantic-scholar:before { + content: "\e96e"; +} +.ai-semantic-scholar-square:before { + content: "\e96c"; +} +.ai-springer:before { + content: "\e928"; +} +.ai-springer-square:before { + content: "\e99b"; +} +.ai-zotero:before { + content: "\e962"; +} +.ai-zotero-square:before { + content: "\e932"; +} +/* Duplication of the FontAwesome style classes using 'ai' in place of 'fa'. */ +.ai-lg { + font-size: 1.33333333em; + line-height: 0.75em; + vertical-align: -15%; +} +.ai-2x { + font-size: 2em; +} +.ai-3x { + font-size: 3em; +} +.ai-4x { + font-size: 4em; +} +.ai-5x { + font-size: 5em; +} +.ai-fw { + width: 1.28571429em; + text-align: center; +} +.ai-ul { + padding-left: 0; + margin-left: 2.14285714em; + list-style-type: none; +} +.ai-ul > li { + position: relative; +} +.ai-li { + position: absolute; + left: -2.14285714em; + width: 2.14285714em; + top: 0.14285714em; + text-align: center; +} +.ai-li.fa-lg { + left: -1.85714286em; +} +.ai-border { + padding: .2em .25em .15em; + border: solid 0.08em #eeeeee; + border-radius: .1em; +} +.ai-pull-left { + float: left; +} +.ai-pull-right { + float: right; +} +.ai.fa-pull-left { + margin-right: .3em; +} +.ai.fa-pull-right { + margin-left: .3em; +} +/* + * Repeat of the FontAwesome style classes to prevent override if academicons.css + * is called after font-awesome.css. + */ +.fa-lg { + font-size: 1.33333333em; + line-height: 0.75em; + vertical-align: -15%; +} +.fa-2x { + font-size: 2em; +} +.fa-3x { + font-size: 3em; +} +.fa-4x { + font-size: 4em; +} +.fa-5x { + font-size: 5em; +} +.fa-fw { + width: 1.28571429em; + text-align: center; +} +.fa-ul { + padding-left: 0; + margin-left: 2.14285714em; + list-style-type: none; +} +.fa-ul > li { + position: relative; +} +.fa-li { + position: absolute; + left: -2.14285714em; + width: 2.14285714em; + top: 0.14285714em; + text-align: center; +} +.fa-li.fa-lg { + left: -1.85714286em; +} +.fa-border { + padding: .2em .25em .15em; + border: solid 0.08em #eeeeee; + border-radius: .1em; +} +.fa-pull-left { + float: left; +} +.fa-pull-right { + float: right; +} +.fa.fa-pull-left { + margin-right: .3em; +} +.fa.fa-pull-right { + margin-left: .3em; +} diff --git a/assets/css/academicons.min.css b/assets/css/academicons.min.css new file mode 100755 index 000000000..09aada772 --- /dev/null +++ b/assets/css/academicons.min.css @@ -0,0 +1 @@ +.ai-ul,.fa-ul{list-style-type:none}.ai-li,.fa-li{top:.14285714em;text-align:center}.ai-fw,.ai-li,.fa-fw,.fa-li{text-align:center}.ai.fa-pull-left,.fa.fa-pull-left{margin-right:.3em}@font-face{font-family:Academicons;src:url(../fonts/academicons.eot?v=1.8.6);src:url(../fonts/academicons.eot?v=1.8.6) format('embedded-opentype'),url(../fonts/academicons.ttf?v=1.8.6) format('truetype'),url(../fonts/academicons.woff?v=1.8.6) format('woff'),url(../fonts/academicons.svg?v=1.8.6#academicons) format('svg');font-weight:400;font-style:normal}.ai{display:inline-block;font:normal normal normal 14px/1 Academicons;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.ai-lg,.fa-lg{line-height:.75em;vertical-align:-15%}.ai-academia:before{content:"\e9af"}.ai-academia-square:before{content:"\e93d"}.ai-acclaim:before{content:"\e92e"}.ai-acclaim-square:before{content:"\e93a"}.ai-acm:before{content:"\e93c"}.ai-acm-square:before{content:"\e95d"}.ai-acmdl:before{content:"\e96a"}.ai-acmdl-square:before{content:"\e9d3"}.ai-ads:before{content:"\e9cb"}.ai-ads-square:before{content:"\e94a"}.ai-arxiv:before{content:"\e974"}.ai-arxiv-square:before{content:"\e9a6"}.ai-biorxiv:before{content:"\e9a2"}.ai-biorxiv-square:before{content:"\e98b"}.ai-ceur:before{content:"\e96d"}.ai-ceur-square:before{content:"\e92f"}.ai-coursera:before{content:"\e95f"}.ai-coursera-square:before{content:"\e97f"}.ai-cv:before{content:"\e9a5"}.ai-cv-square:before{content:"\e90a"}.ai-dataverse:before{content:"\e9f7"}.ai-dataverse-square:before{content:"\e9e4"}.ai-dblp:before{content:"\e94f"}.ai-dblp-square:before{content:"\e93f"}.ai-depsy:before{content:"\e97a"}.ai-depsy-square:before{content:"\e94b"}.ai-doi:before{content:"\e97e"}.ai-doi-square:before{content:"\e98f"}.ai-dryad:before{content:"\e97c"}.ai-dryad-square:before{content:"\e98c"}.ai-figshare:before{content:"\e981"}.ai-figshare-square:before{content:"\e9e7"}.ai-google-scholar:before{content:"\e9d4"}.ai-google-scholar-square:before{content:"\e9f9"}.ai-ideas-repec:before{content:"\e9ed"}.ai-ideas-repec-square:before{content:"\e9f8"}.ai-ieee:before{content:"\e929"}.ai-ieee-square:before{content:"\e9b9"}.ai-impactstory:before{content:"\e9cf"}.ai-impactstory-square:before{content:"\e9aa"}.ai-inspire:before{content:"\e9e9"}.ai-inspire-square:before{content:"\e9fe"}.ai-lattes:before{content:"\e9b3"}.ai-lattes-square:before{content:"\e99c"}.ai-mathoverflow:before{content:"\e9f6"}.ai-mathoverflow-square:before{content:"\e97b"}.ai-mendeley:before{content:"\e9f0"}.ai-mendeley-square:before{content:"\e9f3"}.ai-open-access:before{content:"\e939"}.ai-open-access-square:before{content:"\e9f4"}.ai-orcid:before{content:"\e9d9"}.ai-orcid-square:before{content:"\e9c3"}.ai-osf:before{content:"\e9ef"}.ai-osf-square:before{content:"\e931"}.ai-overleaf:before{content:"\e914"}.ai-overleaf-square:before{content:"\e98d"}.ai-philpapers:before{content:"\e98a"}.ai-philpapers-square:before{content:"\e96f"}.ai-piazza:before{content:"\e99a"}.ai-piazza-square:before{content:"\e90c"}.ai-publons:before{content:"\e937"}.ai-publons-square:before{content:"\e94e"}.ai-pubmed:before{content:"\e99f"}.ai-pubmed-square:before{content:"\e97d"}.ai-researcherid:before{content:"\e91a"}.ai-researcherid-square:before{content:"\e95c"}.ai-researchgate:before{content:"\e95e"}.ai-researchgate-square:before{content:"\e99e"}.ai-scirate:before{content:"\e98e"}.ai-scirate-square:before{content:"\e99d"}.ai-semantic-scholar:before{content:"\e96e"}.ai-semantic-scholar-square:before{content:"\e96c"}.ai-springer:before{content:"\e928"}.ai-springer-square:before{content:"\e99b"}.ai-zotero:before{content:"\e962"}.ai-zotero-square:before{content:"\e932"}.ai-lg{font-size:1.33333333em}.ai-2x{font-size:2em}.ai-3x{font-size:3em}.ai-4x{font-size:4em}.ai-5x{font-size:5em}.ai-fw{width:1.28571429em}.ai-ul{padding-left:0;margin-left:2.14285714em}.ai-ul>li{position:relative}.ai-li{position:absolute;left:-2.14285714em;width:2.14285714em}.ai-li.fa-lg{left:-1.85714286em}.ai-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.ai-pull-left{float:left}.ai-pull-right{float:right}.ai.fa-pull-right{margin-left:.3em}.fa-lg{font-size:1.33333333em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em}.fa-ul{padding-left:0;margin-left:2.14285714em}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-right{margin-left:.3em} \ No newline at end of file diff --git a/assets/css/main.css b/assets/css/main.css new file mode 100644 index 000000000..67f72c55e --- /dev/null +++ b/assets/css/main.css @@ -0,0 +1,5 @@ +@font-face{font-family:"Atkinson-Hyperlegible";src:url("../fonts/atkinson-hyperlegible-regular-102a.woff2");font-weight:400;font-style:normal}@font-face{font-family:"Atkinson-Hyperlegible";src:url("../fonts/atkinson-hyperlegible-bold-102a.woff2");font-weight:700;font-style:normal}@font-face{font-family:"Cartridge";src:url("../fonts/Cartridge-Regular.woff2");font-weight:400;font-style:normal}@font-face{font-family:"Cartridge";src:url("../fonts/Cartridge-Bold.woff2");font-weight:700;font-style:normal}.author__urls.social-icons .svg-inline--fa,.author__urls.social-icons .svg-inline--fab,.page__footer-follow .social-icons .svg-inline--fa{color:inherit}.ais-search-box .ais-search-box--input{background-color:#1f242c}.audience{color:#186459;font-weight:bold;display:block}.wiki-flex{display:flex;flex-flow:row wrap;justify-content:space-between;align-items:center}.wiki-flex-item{flex:1;text-align:center}.wiki-folder-grid{display:flex;flex-flow:row wrap;justify-content:flex-start;align-items:center}.wiki-folder-grid-thirds{flex:none;flex-basis:calc(100%/3);text-align:center;padding:.5em .5em .5em .5em}.backlink-box{background:#21262f;padding:1em;border-radius:4px;border-width:1px;border-style:solid;border-color:#51555d;position:relative}.backlink-box:hover{box-shadow:0 0 0 0.25rem #fb802f}.backlink-box a::after{content:'';position:absolute;top:0;right:0;bottom:0;left:0}.backlink-box a{text-decoration:underline}.backlink-box a:focus{text-decoration:underline}.backlink-box:focus-within{box-shadow:0 0 0 0.25rem #fb802f}.backlink-box:focus-within a:focus{text-decoration:underline}details summary{outline:2px solid #51555d;cursor:pointer;padding:.5rem 1rem}details summary>*{display:inline}details>div{border:2px solid #51555d;margin-top:0;padding:1rem}details{padding:.5rem}summary:hover{box-shadow:0 0 0 0.35rem #33dab1}.list-unstyled{list-style:none;padding:0}progress{-webkit-appearance:none}::-webkit-progress-value{background-color:#00D19D}::-moz-progress-bar{background-color:#00D19D}h1,h2,h3,h4,h5,h6{color:#00D19D}.footnote{color:#d2d2d2 !important;text-decoration:none}.footnotes{color:#d2d2d2 !important}.btn--primary{background-color:#ff944d !important;color:#242424 !important}.btn--primary:visited{background-color:#db8043 !important;color:#030303 !important}.btn--primary:hover{background-color:#fc9959 !important;color:#030303 !important}.nav__title{background-color:#ff8b3d !important;color:#1f1f1f !important}/*! + * Minimal Mistakes Jekyll Theme 4.17.2 by Michael Rose + * Copyright 2013-2019 Michael Rose - mademistakes.com | @mmistakes + * Licensed under MIT (https://github.com/mmistakes/minimal-mistakes/blob/master/LICENSE) +*/.mfp-counter{font-family:Georgia,Times,serif}.mfp-bg{top:0;left:0;width:100%;height:100%;z-index:1042;overflow:hidden;position:fixed;background:#000;opacity:.8;filter:alpha(opacity=80)}.mfp-wrap{top:0;left:0;width:100%;height:100%;z-index:1043;position:fixed;outline:none !important;-webkit-backface-visibility:hidden}.mfp-container{text-align:center;position:absolute;width:100%;height:100%;left:0;top:0;padding:0 8px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.mfp-container:before{content:'';display:inline-block;height:100%;vertical-align:middle}.mfp-align-top .mfp-container:before{display:none}.mfp-content{position:relative;display:inline-block;vertical-align:middle;margin:0 auto;text-align:left;z-index:1045}.mfp-inline-holder .mfp-content,.mfp-ajax-holder .mfp-content{width:100%;cursor:auto}.mfp-ajax-cur{cursor:progress}.mfp-zoom-out-cur,.mfp-zoom-out-cur .mfp-image-holder .mfp-close{cursor:-moz-zoom-out;cursor:-webkit-zoom-out;cursor:zoom-out}.mfp-zoom{cursor:pointer;cursor:-webkit-zoom-in;cursor:-moz-zoom-in;cursor:zoom-in}.mfp-auto-cursor .mfp-content{cursor:auto}.mfp-close,.mfp-arrow,.mfp-preloader,.mfp-counter{-webkit-user-select:none;-moz-user-select:none;user-select:none}.mfp-loading.mfp-figure{display:none}.mfp-hide{display:none !important}.mfp-preloader{color:#ccc;position:absolute;top:50%;width:auto;text-align:center;margin-top:-0.8em;left:8px;right:8px;z-index:1044}.mfp-preloader a{color:#ccc}.mfp-preloader a:hover{color:#fff}.mfp-s-ready .mfp-preloader{display:none}.mfp-s-error .mfp-content{display:none}button.mfp-close,button.mfp-arrow{overflow:visible;cursor:pointer;background:transparent;border:0;-webkit-appearance:none;display:block;outline:none;padding:0;z-index:1046;-webkit-box-shadow:none;box-shadow:none}button::-moz-focus-inner{padding:0;border:0}.mfp-close{width:44px;height:44px;line-height:44px;position:absolute;right:0;top:0;text-decoration:none;text-align:center;opacity:1;filter:alpha(opacity=100);padding:0 0 18px 10px;color:#fff;font-style:normal;font-size:28px;font-family:Georgia,Times,serif}.mfp-close:hover,.mfp-close:focus{opacity:1;filter:alpha(opacity=100)}.mfp-close:active{top:1px}.mfp-close-btn-in .mfp-close{color:#fff}.mfp-image-holder .mfp-close,.mfp-iframe-holder .mfp-close{color:#fff;right:-6px;text-align:right;padding-right:6px;width:100%}.mfp-counter{position:absolute;top:0;right:0;color:#ccc;font-size:12px;line-height:18px}.mfp-arrow{position:absolute;opacity:1;filter:alpha(opacity=100);margin:0;top:50%;margin-top:-55px;padding:0;width:90px;height:110px;-webkit-tap-highlight-color:transparent}.mfp-arrow:active{margin-top:-54px}.mfp-arrow:hover,.mfp-arrow:focus{opacity:1;filter:alpha(opacity=100)}.mfp-arrow:before,.mfp-arrow:after,.mfp-arrow .mfp-b,.mfp-arrow .mfp-a{content:'';display:block;width:0;height:0;position:absolute;left:0;top:0;margin-top:35px;margin-left:35px;border:medium inset transparent}.mfp-arrow:after,.mfp-arrow .mfp-a{border-top-width:13px;border-bottom-width:13px;top:8px}.mfp-arrow:before,.mfp-arrow .mfp-b{border-top-width:21px;border-bottom-width:21px;opacity:0.7}.mfp-arrow-left{left:0}.mfp-arrow-left:after,.mfp-arrow-left .mfp-a{border-right:17px solid #fff;margin-left:31px}.mfp-arrow-left:before,.mfp-arrow-left .mfp-b{margin-left:25px;border-right:27px solid #fff}.mfp-arrow-right{right:0}.mfp-arrow-right:after,.mfp-arrow-right .mfp-a{border-left:17px solid #fff;margin-left:39px}.mfp-arrow-right:before,.mfp-arrow-right .mfp-b{border-left:27px solid #fff}.mfp-iframe-holder{padding-top:40px;padding-bottom:40px}.mfp-iframe-holder .mfp-content{line-height:0;width:100%;max-width:900px}.mfp-iframe-holder .mfp-close{top:-40px}.mfp-iframe-scaler{width:100%;height:0;overflow:hidden;padding-top:56.25%}.mfp-iframe-scaler iframe{position:absolute;display:block;top:0;left:0;width:100%;height:100%;box-shadow:0 0 8px rgba(0,0,0,0.6);background:#000}img.mfp-img{width:auto;max-width:100%;height:auto;display:block;line-height:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:40px 0 40px;margin:0 auto}.mfp-figure{line-height:0}.mfp-figure:after{content:'';position:absolute;left:0;top:40px;bottom:40px;display:block;right:0;width:auto;height:auto;z-index:-1;box-shadow:0 0 8px rgba(0,0,0,0.6);background:#444}.mfp-figure small{color:#bdbdbd;display:block;font-size:12px;line-height:14px}.mfp-figure figure{margin:0}.mfp-figure figcaption{margin-top:0;margin-bottom:0}.mfp-bottom-bar{margin-top:-36px;position:absolute;top:100%;left:0;width:100%;cursor:auto}.mfp-title{text-align:left;line-height:18px;color:#f3f3f3;word-wrap:break-word;padding-right:36px}.mfp-image-holder .mfp-content{max-width:100%}.mfp-gallery .mfp-image-holder .mfp-figure{cursor:pointer}@media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px){.mfp-img-mobile .mfp-image-holder{padding-left:0;padding-right:0}.mfp-img-mobile img.mfp-img{padding:0}.mfp-img-mobile .mfp-figure:after{top:0;bottom:0}.mfp-img-mobile .mfp-figure small{display:inline;margin-left:5px}.mfp-img-mobile .mfp-bottom-bar{background:rgba(0,0,0,0.6);bottom:0;margin:0;top:auto;padding:3px 5px;position:fixed;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.mfp-img-mobile .mfp-bottom-bar:empty{padding:0}.mfp-img-mobile .mfp-counter{right:5px;top:3px}.mfp-img-mobile .mfp-close{top:0;right:0;width:35px;height:35px;line-height:35px;background:rgba(0,0,0,0.6);position:fixed;text-align:center;padding:0}}@media all and (max-width: 900px){.mfp-arrow{-webkit-transform:scale(0.75);transform:scale(0.75)}.mfp-arrow-left{-webkit-transform-origin:0;transform-origin:0}.mfp-arrow-right{-webkit-transform-origin:100%;transform-origin:100%}.mfp-container{padding-left:6px;padding-right:6px}}.mfp-ie7 .mfp-img{padding:0}.mfp-ie7 .mfp-bottom-bar{width:600px;left:50%;margin-left:-300px;margin-top:5px;padding-bottom:5px}.mfp-ie7 .mfp-container{padding:0}.mfp-ie7 .mfp-content{padding-top:44px}.mfp-ie7 .mfp-close{top:0;right:0;padding-top:0}a:focus,button:focus{outline:0.2rem solid #f60;outline-offset:-2px;box-shadow:0 0 0 .3rem #f0f0f0}*{box-sizing:border-box}html{box-sizing:border-box;background-color:#252a34;font-size:16px;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}@media (min-width: 48em){html{font-size:18px}}@media (min-width: 64em){html{font-size:20px}}@media (min-width: 80em){html{font-size:22px}}body{margin:0}::-moz-selection{color:#fff;background:#000}::selection{color:#fff;background:#000}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}a{color:#fb802f}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{max-width:100%;width:auto\9;height:auto;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}input[type="search"]{box-sizing:border-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}html{position:relative;min-height:100%}body{margin:0;padding:0;color:#eaeaea;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;line-height:1.5}body.overflow--hidden{overflow:hidden}h1,h2,h3,h4,h5,h6{margin:2em 0 0.5em;line-height:1.2;font-family:"Cartridge","Roboto","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-weight:bold}h1{margin-top:0;font-size:1.563em}h2{font-size:1.25em}h3{font-size:1em}h4{font-size:.75em}h5{font-size:.75em}h6{font-size:.75em}small,.small{font-size:.75em}p{margin-bottom:1.3em}u,ins{text-decoration:none;border-bottom:1px solid #eaeaea}u a,ins a{color:inherit}del a{color:inherit}p,pre,blockquote,ul,ol,dl,figure,table,fieldset{orphans:3;widows:3}abbr[title],abbr[data-original-title]{text-decoration:none;cursor:help;border-bottom:1px dotted #eaeaea}blockquote{margin:2em 1em 2em 0;padding-left:1em;padding-right:1em;font-style:italic;border-left:0.25em solid #f60}blockquote cite{font-style:italic}blockquote cite:before{content:"\2014";padding-right:5px}a:visited{color:#c96626}a:hover{color:#fc9959;outline:0}tt,code,kbd,samp,pre{font-family:Monaco,Consolas,"Lucida Console",monospace}pre{overflow-x:auto}p>code,a>code,li>code,figcaption>code,td>code{padding-top:0.1rem;padding-bottom:0.1rem;font-size:0.8em;background:#1f242c;border-radius:4px}p>code:before,p>code:after,a>code:before,a>code:after,li>code:before,li>code:after,figcaption>code:before,figcaption>code:after,td>code:before,td>code:after{letter-spacing:-0.2em;content:"\00a0"}hr{display:block;margin:1em 0;border:0;border-top:1px solid #51555d}ul li,ol li{margin-bottom:0.5em}li ul,li ol{margin-top:0.5em}figure{display:-webkit-box;display:flex;-webkit-box-pack:justify;justify-content:space-between;-webkit-box-align:start;align-items:flex-start;flex-wrap:wrap;margin:2em 0}figure img,figure iframe,figure .fluid-width-video-wrapper{margin-bottom:1em}figure img{width:100%;border-radius:4px;-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}figure>a{display:block}@media (min-width: 37.5em){figure.half>a,figure.half>img{width:calc(50% - 0.5em)}}figure.half figcaption{width:100%}@media (min-width: 37.5em){figure.third>a,figure.third>img{width:calc(33.3333% - 0.5em)}}figure.third figcaption{width:100%}figcaption{margin-bottom:0.5em;color:#eee;font-family:sans-serif;font-size:.75em}figcaption a{-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}figcaption a:hover{color:#fc9959}svg:not(:root){overflow:hidden}nav ul{margin:0;padding:0}nav li{list-style:none}nav a{text-decoration:none}nav ul li,nav ol li{margin-bottom:0}nav li ul,nav li ol{margin-top:0}b,i,strong,em,blockquote,p,q,span,figure,img,h1,h2,header,input,a,tr,td,form button,input[type="submit"],.btn,#goog-wm-sb,.highlight,.archive__item-teaser{-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}form{margin:0 0 5px 0;padding:1em;background-color:#1f242c}form fieldset{margin-bottom:5px;padding:0;border-width:0}form legend{display:block;width:100%;margin-bottom:10px;*margin-left:-7px;padding:0;color:#eaeaea;border:0;white-space:normal}form p{margin-bottom:2.5px}form ul{list-style-type:none;margin:0 0 5px 0;padding:0}form br{display:none}label,input,button,select,textarea{vertical-align:baseline;*vertical-align:middle}input,button,select,textarea{box-sizing:border-box;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif}label{display:block;margin-bottom:0.25em;color:#eaeaea;cursor:pointer}label small{font-size:.75em}label input,label textarea,label select{display:block}input,textarea,select{display:inline-block;width:100%;padding:0.25em;margin-bottom:0.5em;color:#eaeaea;background-color:#252a34;border:#51555d;border-radius:4px;box-shadow:0 1px 1px rgba(0,0,0,0.125)}.input-mini{width:60px}.input-small{width:90px}input[type="image"],input[type="checkbox"],input[type="radio"]{width:auto;height:auto;padding:0;margin:3px 0;*margin-top:0;line-height:normal;cursor:pointer;border-radius:0;border:0 \9}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*width:13px;*height:13px}input[type="image"]{border:0;box-shadow:none}input[type="file"]{width:auto;padding:initial;line-height:initial;border:initial;background-color:transparent;background-color:initial;box-shadow:none}input[type="button"],input[type="reset"],input[type="submit"]{width:auto;height:auto;cursor:pointer;*overflow:visible}select,input[type="file"]{*margin-top:4px}select{width:auto;background-color:#fff}select[multiple],select[size]{height:auto}textarea{resize:vertical;height:auto;overflow:auto;vertical-align:top}input[type="hidden"]{display:none}.form{position:relative}.radio,.checkbox{padding-left:18px;font-weight:normal}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-18px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{opacity:0.5;cursor:not-allowed}input:focus,textarea:focus{border-color:#f60;outline:0;outline:thin dotted \9;box-shadow:inset 0 1px 3px rgba(234,234,234,0.06),0 0 5px rgba(255,102,0,0.7)}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus,select:focus{box-shadow:none}.help-block,.help-inline{color:#eee}.help-block{display:block;margin-bottom:1em;line-height:1em}.help-inline{display:inline-block;vertical-align:middle;padding-left:5px}.form-group{margin-bottom:5px;padding:0;border-width:0}.form-inline input,.form-inline textarea,.form-inline select{display:inline-block;margin-bottom:0}.form-inline label{display:inline-block}.form-inline .radio,.form-inline .checkbox,.form-inline .radio{padding-left:0;margin-bottom:0;vertical-align:middle}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-left:0;margin-right:3px}.form-search input,.form-search textarea,.form-search select{display:inline-block;margin-bottom:0}.form-search .search-query{padding-left:14px;padding-right:14px;margin-bottom:0;border-radius:14px}.form-search label{display:inline-block}.form-search .radio,.form-search .checkbox,.form-inline .radio{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"]{float:left;margin-left:0;margin-right:3px}.form--loading:before{content:""}.form--loading .form__spinner{display:block}.form:before{position:absolute;top:0;left:0;width:100%;height:100%;background-color:rgba(255,255,255,0.7);z-index:10}.form__spinner{display:none;position:absolute;top:50%;left:50%;z-index:11}#goog-fixurl ul{list-style:none;margin-left:0;padding-left:0}#goog-fixurl ul li{list-style-type:none}#goog-wm-qt{width:auto;margin-right:10px;margin-bottom:20px;padding:8px 20px;display:inline-block;font-size:.75em;background-color:#fff;color:#000;border-width:2px !important;border-style:solid !important;border-color:#51555d;border-radius:4px}table{display:block;margin-bottom:1em;width:100%;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em;border-collapse:collapse;overflow-x:auto}table+table{margin-top:1em}thead{background-color:#51555d;border-bottom:2px solid #3d4046}th{padding:0.5em;font-weight:bold;text-align:left}td{padding:0.5em;border-bottom:1px solid #3d4046}tr,td,th{vertical-align:middle}@-webkit-keyframes intro{0%{opacity:0}100%{opacity:1}}@keyframes intro{0%{opacity:0}100%{opacity:1}}.btn,#goog-wm-sb{display:inline-block;margin-bottom:0.25em;padding:0.5em 1em;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em;font-weight:bold;text-align:center;text-decoration:none;border-width:0;border-radius:4px;cursor:pointer}.btn .icon,#goog-wm-sb .icon{margin-right:0.5em}.btn .icon+.hidden,#goog-wm-sb .icon+.hidden{margin-left:-0.5em}.btn--primary{background-color:#f60;color:#fff}.btn--primary:visited{background-color:#f60;color:#fff}.btn--primary:hover{background-color:#cc5200;color:#fff}.btn--inverse{background-color:#fff;color:#3d4144;border:1px solid #51555d}.btn--inverse:visited{background-color:#fff;color:#3d4144}.btn--inverse:hover{background-color:#ccc;color:#3d4144}.btn--light-outline{background-color:transparent;color:#fff;border:1px solid #fff}.btn--light-outline:visited{background-color:transparent;color:#fff}.btn--light-outline:hover{background-color:rgba(0,0,0,0.2);color:#fff}.btn--success{background-color:#3fa63f;color:#fff}.btn--success:visited{background-color:#3fa63f;color:#fff}.btn--success:hover{background-color:#328532;color:#fff}.btn--warning{background-color:#d67f05;color:#fff}.btn--warning:visited{background-color:#d67f05;color:#fff}.btn--warning:hover{background-color:#ab6604;color:#fff}.btn--danger{background-color:#ee5f5b;color:#fff}.btn--danger:visited{background-color:#ee5f5b;color:#fff}.btn--danger:hover{background-color:#be4c49;color:#fff}.btn--info{background-color:#3b9cba;color:#fff}.btn--info:visited{background-color:#3b9cba;color:#fff}.btn--info:hover{background-color:#2f7d95;color:#fff}.btn--facebook{background-color:#3b5998;color:#fff}.btn--facebook:visited{background-color:#3b5998;color:#fff}.btn--facebook:hover{background-color:#2f477a;color:#fff}.btn--twitter{background-color:#55acee;color:#fff}.btn--twitter:visited{background-color:#55acee;color:#fff}.btn--twitter:hover{background-color:#448abe;color:#fff}.btn--linkedin{background-color:#007bb6;color:#fff}.btn--linkedin:visited{background-color:#007bb6;color:#fff}.btn--linkedin:hover{background-color:#006292;color:#fff}.btn--block{display:block;width:100%}.btn--block+.btn--block{margin-top:0.25em}.btn--disabled{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);box-shadow:none;opacity:0.65}.btn--x-large{font-size:1.25em}.btn--large{font-size:1em}.btn--small{font-size:.6875em}.notice{margin:2em 0 !important;padding:1em;color:#eaeaea;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em !important;text-indent:initial;background-color:#434851;border-radius:4px;box-shadow:0 1px 1px rgba(189,193,196,0.25)}.notice h4{margin-top:0 !important;margin-bottom:0.75em;line-height:inherit}.page__content .notice h4{margin-bottom:0;font-size:1em}.notice p:last-child{margin-bottom:0 !important}.notice h4+p{margin-top:0;padding-top:0}.notice a{color:#aaaeb0}.notice a:hover{color:#5f6162}.notice code{background-color:#343942}.notice pre code{background-color:inherit}.notice ul:last-child{margin-bottom:0}.notice--primary{margin:2em 0 !important;padding:1em;color:#eaeaea;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em !important;text-indent:initial;background-color:#51362a;border-radius:4px;box-shadow:0 1px 1px rgba(255,102,0,0.25)}.notice--primary h4{margin-top:0 !important;margin-bottom:0.75em;line-height:inherit}.page__content .notice--primary h4{margin-bottom:0;font-size:1em}.notice--primary p:last-child{margin-bottom:0 !important}.notice--primary h4+p{margin-top:0;padding-top:0}.notice--primary a{color:#e65c00}.notice--primary a:hover{color:#803300}.notice--primary code{background-color:#3b302f}.notice--primary pre code{background-color:inherit}.notice--primary ul:last-child{margin-bottom:0}.notice--info{margin:2em 0 !important;padding:1em;color:#eaeaea;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em !important;text-indent:initial;background-color:#29414f;border-radius:4px;box-shadow:0 1px 1px rgba(59,156,186,0.25)}.notice--info h4{margin-top:0 !important;margin-bottom:0.75em;line-height:inherit}.page__content .notice--info h4{margin-bottom:0;font-size:1em}.notice--info p:last-child{margin-bottom:0 !important}.notice--info h4+p{margin-top:0;padding-top:0}.notice--info a{color:#358ca7}.notice--info a:hover{color:#1e4e5d}.notice--info code{background-color:#273541}.notice--info pre code{background-color:inherit}.notice--info ul:last-child{margin-bottom:0}.notice--warning{margin:2em 0 !important;padding:1em;color:#eaeaea;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em !important;text-indent:initial;background-color:#483b2b;border-radius:4px;box-shadow:0 1px 1px rgba(214,127,5,0.25)}.notice--warning h4{margin-top:0 !important;margin-bottom:0.75em;line-height:inherit}.page__content .notice--warning h4{margin-bottom:0;font-size:1em}.notice--warning p:last-child{margin-bottom:0 !important}.notice--warning h4+p{margin-top:0;padding-top:0}.notice--warning a{color:#c17205}.notice--warning a:hover{color:#6b4003}.notice--warning code{background-color:#37332f}.notice--warning pre code{background-color:inherit}.notice--warning ul:last-child{margin-bottom:0}.notice--success{margin:2em 0 !important;padding:1em;color:#eaeaea;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em !important;text-indent:initial;background-color:#2a4336;border-radius:4px;box-shadow:0 1px 1px rgba(63,166,63,0.25)}.notice--success h4{margin-top:0 !important;margin-bottom:0.75em;line-height:inherit}.page__content .notice--success h4{margin-bottom:0;font-size:1em}.notice--success p:last-child{margin-bottom:0 !important}.notice--success h4+p{margin-top:0;padding-top:0}.notice--success a{color:#399539}.notice--success a:hover{color:#205320}.notice--success code{background-color:#283635}.notice--success pre code{background-color:inherit}.notice--success ul:last-child{margin-bottom:0}.notice--danger{margin:2em 0 !important;padding:1em;color:#eaeaea;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em !important;text-indent:initial;background-color:#4d353c;border-radius:4px;box-shadow:0 1px 1px rgba(238,95,91,0.25)}.notice--danger h4{margin-top:0 !important;margin-bottom:0.75em;line-height:inherit}.page__content .notice--danger h4{margin-bottom:0;font-size:1em}.notice--danger p:last-child{margin-bottom:0 !important}.notice--danger h4+p{margin-top:0;padding-top:0}.notice--danger a{color:#d65652}.notice--danger a:hover{color:#77302e}.notice--danger code{background-color:#392f38}.notice--danger pre code{background-color:inherit}.notice--danger ul:last-child{margin-bottom:0}.masthead{position:relative;border-bottom:1px solid #51555d;-webkit-animation:intro 0.3s both;animation:intro 0.3s both;-webkit-animation-delay:0.15s;animation-delay:0.15s;z-index:20}.masthead__inner-wrap{clear:both;margin-left:auto;margin-right:auto;padding:1em;max-width:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif}.masthead__inner-wrap::after{clear:both;content:"";display:table}@media (min-width: 80em){.masthead__inner-wrap{max-width:1280px}}.masthead__inner-wrap nav{z-index:10}.masthead__inner-wrap a{text-decoration:none}.site-logo img{max-height:2rem}.site-title{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-item-align:center;align-self:center;font-weight:bold;z-index:20}.site-subtitle{display:block;font-size:.625em}.masthead__menu{float:left;margin-left:0;margin-right:0;width:100%;clear:both}.masthead__menu .site-nav{margin-left:0}@media (min-width: 37.5em){.masthead__menu .site-nav{float:right}}.masthead__menu ul{margin:0;padding:0;clear:both;list-style-type:none}.masthead__menu-item{display:block;list-style-type:none;white-space:nowrap}.masthead__menu-item--lg{padding-right:2em;font-weight:700}.breadcrumbs{clear:both;margin:0 auto;max-width:100%;padding-left:1em;padding-right:1em;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;-webkit-animation:intro 0.3s both;animation:intro 0.3s both;-webkit-animation-delay:0.3s;animation-delay:0.3s}.breadcrumbs::after{clear:both;content:"";display:table}@media (min-width: 80em){.breadcrumbs{max-width:1280px}}.breadcrumbs ol{padding:0;list-style:none;font-size:.75em}@media (min-width: 64em){.breadcrumbs ol{float:right;width:calc(100% - 200px)}}@media (min-width: 80em){.breadcrumbs ol{width:calc(100% - 300px)}}.breadcrumbs li{display:inline}.breadcrumbs .current{font-weight:bold}.pagination{clear:both;float:left;margin-top:1em;padding-top:1em;width:100%}.pagination::after{clear:both;content:"";display:table}.pagination ul{margin:0;padding:0;list-style-type:none;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif}.pagination li{display:block;float:left;margin-left:-1px}.pagination li a{display:block;margin-bottom:0.25em;padding:0.5em 1em;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:14px;font-weight:bold;line-height:1.5;text-align:center;text-decoration:none;color:#eee;border:1px solid #3d4046;border-radius:0}.pagination li a:hover{color:#fc9959}.pagination li a.current,.pagination li a.current.disabled{color:#252a34;background:#f60}.pagination li a.disabled{color:rgba(238,238,238,0.5);pointer-events:none;cursor:not-allowed}.pagination li:first-child{margin-left:0}.pagination li:first-child a{border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination li:last-child a{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination--pager{display:block;padding:1em 2em;float:left;width:50%;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:1em;font-weight:bold;text-align:center;text-decoration:none;color:#eee;border:1px solid #3d4046;border-radius:4px}.pagination--pager:hover{background-color:#eee;color:#3d4144}.pagination--pager:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.pagination--pager:last-child{margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.pagination--pager.disabled{color:rgba(238,238,238,0.5);pointer-events:none;cursor:not-allowed}.page__content+.pagination,.page__meta+.pagination,.comment__date+.pagination,.page__share+.pagination,.page__comments+.pagination{margin-top:2em;padding-top:2em;border-top:1px solid #51555d}.greedy-nav{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;min-height:2em;background:#252a34}.greedy-nav a{display:block;margin:1rem;color:#00D19D;text-decoration:none}.greedy-nav a:hover{color:#33dab1}.greedy-nav a.site-logo{margin-left:0;margin-right:0.5rem}.greedy-nav a.site-title{margin-left:0}.greedy-nav__toggle{-ms-flex-item-align:center;align-self:center;height:2rem;border:0;outline:none;background-color:transparent;cursor:pointer}.greedy-nav .visible-links{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;-webkit-box-flex:1;-ms-flex:1;flex:1;overflow:hidden}.greedy-nav .visible-links li{-webkit-box-flex:0;-ms-flex:none;flex:none}.greedy-nav .visible-links a{position:relative}.greedy-nav .visible-links a:before{content:"";position:absolute;left:0;bottom:0;height:4px;background:#f60;width:100%;-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out;-webkit-transform:scaleX(0) translate3d(0, 0, 0);transform:scaleX(0) translate3d(0, 0, 0)}.greedy-nav .visible-links a:hover:before{-webkit-transform:scaleX(1);-ms-transform:scaleX(1);transform:scaleX(1)}.greedy-nav .hidden-links{position:absolute;top:100%;right:0;margin-top:15px;padding:5px;border:1px solid #51555d;border-radius:4px;background:#252a34;-webkit-box-shadow:0 2px 4px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12);box-shadow:0 2px 4px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12)}.greedy-nav .hidden-links.hidden{display:none}.greedy-nav .hidden-links a{margin:0;padding:10px 20px;font-size:1em}.greedy-nav .hidden-links a:hover{color:#33dab1;background:#1a1d24}.greedy-nav .hidden-links:before{content:"";position:absolute;top:-11px;right:10px;width:0;border-style:solid;border-width:0 10px 10px;border-color:#51555d transparent;display:block;z-index:0}.greedy-nav .hidden-links:after{content:"";position:absolute;top:-10px;right:10px;width:0;border-style:solid;border-width:0 10px 10px;border-color:#252a34 transparent;display:block;z-index:1}.greedy-nav .hidden-links li{display:block;border-bottom:1px solid #51555d}.greedy-nav .hidden-links li:last-child{border-bottom:none}.no-js .greedy-nav .visible-links{-ms-flex-wrap:wrap;flex-wrap:wrap;overflow:visible}.nav__list{margin-bottom:1.5em}.nav__list input[type="checkbox"],.nav__list label{display:none}@media (max-width: 63.9375em){.nav__list label{position:relative;display:inline-block;padding:0.5em 2.5em 0.5em 1em;color:#7a8288;font-size:.75em;font-weight:bold;border:1px solid #bdc1c4;border-radius:4px;z-index:20;-webkit-transition:0.2s ease-out;transition:0.2s ease-out;cursor:pointer}.nav__list label:before,.nav__list label:after{content:"";position:absolute;right:1em;top:1.25em;width:0.75em;height:0.125em;line-height:1;background-color:#7a8288;-webkit-transition:0.2s ease-out;transition:0.2s ease-out}.nav__list label:after{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.nav__list label:hover{color:#fff;border-color:#7a8288;background-color:#333}.nav__list label:hover:before,.nav__list label:hover:after{background-color:#fff}.nav__list input:checked+label{color:white;background-color:#333}.nav__list input:checked+label:before,.nav__list input:checked+label:after{background-color:#fff}.nav__list label:hover:after{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.nav__list input:checked+label:hover:after{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}.nav__list ul{margin-bottom:1em}.nav__list a{display:block;padding:0.25em 0}}@media (max-width: 63.9375em) and (min-width: 64em){.nav__list a{padding-top:0.125em;padding-bottom:0.125em}}@media (max-width: 63.9375em){.nav__list a:hover{text-decoration:underline}}.nav__list .nav__items{margin:0;font-size:1.25rem}.nav__list .nav__items a{color:inherit}.nav__list .nav__items .active{margin-left:-0.5em;padding-left:0.5em;padding-right:0.5em;font-weight:bold}@media (max-width: 63.9375em){.nav__list .nav__items{position:relative;max-height:0;opacity:0%;overflow:hidden;z-index:10;-webkit-transition:0.3s ease-in-out;transition:0.3s ease-in-out;-webkit-transform:translate(0, 10%);-ms-transform:translate(0, 10%);transform:translate(0, 10%)}}@media (max-width: 63.9375em){.nav__list input:checked ~ .nav__items{-webkit-transition:0.5s ease-in-out;transition:0.5s ease-in-out;max-height:9999px;overflow:visible;opacity:1;margin-top:1em;-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);transform:translate(0, 0)}}.nav__title{margin:0;padding:0.5rem 0.75rem;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:1em;font-weight:bold}.nav__sub-title{display:block;margin:0.5rem 0;padding:0.25rem 0;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em;font-weight:bold;text-transform:uppercase;border-bottom:1px solid #51555d}.toc{font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;color:#7a8288;background-color:#252a34;border:1px solid #51555d;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.125);box-shadow:0 1px 1px rgba(0,0,0,0.125)}.toc .nav__title{color:#fff;font-size:.75em;background:#f60;border-top-left-radius:4px;border-top-right-radius:4px}.toc .active a{box-shadow:0 0 0 0.1rem #c67d50}.toc__menu{margin:0;padding:0;width:100%;list-style:none;font-size:.75em}@media (min-width: 64em){.toc__menu{font-size:.6875em}}.toc__menu a{display:block;padding:0.25rem 0.75rem;color:#00D19D;font-weight:bold;line-height:1.5;border-bottom:1px solid #51555d}.toc__menu a:hover{color:#eaeaea}.toc__menu li ul>li a{padding-left:1.25rem;font-weight:normal}.toc__menu li ul li ul>li a{padding-left:1.75rem}.toc__menu li ul li ul li ul>li a{padding-left:2.25rem}.toc__menu li ul li ul li ul li ul>li a{padding-left:2.75rem}.toc__menu li ul li ul li ul li ul li ul>li a{padding-left:3.25rem}.page__footer{clear:both;float:left;margin-left:0;margin-right:0;width:100%;clear:both;margin-top:3em;color:#eee;-webkit-animation:intro 0.3s both;animation:intro 0.3s both;-webkit-animation-delay:0.45s;animation-delay:0.45s;background-color:#1a1d24}.page__footer::after{clear:both;content:"";display:table}.page__footer footer{clear:both;margin-left:auto;margin-right:auto;margin-top:2em;max-width:100%;padding:0 1em 2em}.page__footer footer::after{clear:both;content:"";display:table}@media (min-width: 80em){.page__footer footer{max-width:1280px}}.page__footer a{color:inherit;text-decoration:none}.page__footer a:hover{text-decoration:underline}.page__footer .fas,.page__footer .fab,.page__footer .far,.page__footer .fal{color:#eee}.page__footer-copyright{font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.6875em}.page__footer-follow ul{margin:0;padding:0;list-style-type:none}.page__footer-follow li{display:inline-block;padding-top:5px;padding-bottom:5px;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em;text-transform:uppercase}.page__footer-follow li+li:before{content:"";padding-right:5px}.page__footer-follow a{padding-right:10px;font-weight:bold}.page__footer-follow .social-icons a{white-space:nowrap}.layout--search .archive__item-teaser{margin-bottom:0.25em}.search__toggle{margin-left:1rem;margin-right:1rem;height:2rem;border:0;outline:none;color:#f60;background-color:transparent;cursor:pointer;-webkit-transition:0.2s;transition:0.2s}.search__toggle:hover{color:#bf4d00}.search-icon{width:100%;height:100%}.search-content{display:none;visibility:hidden;padding-top:1em;padding-bottom:1em}.search-content__inner-wrap{width:100%;margin-left:auto;margin-right:auto;padding-left:1em;padding-right:1em;-webkit-animation:intro 0.3s both;animation:intro 0.3s both;-webkit-animation-delay:0.15s;animation-delay:0.15s}@media (min-width: 80em){.search-content__inner-wrap{max-width:1280px}}.search-content__form{background-color:transparent}.search-content .search-input{display:block;margin-bottom:0;padding:0;border:none;outline:none;box-shadow:none;background-color:transparent;font-size:1.563em}@media (min-width: 64em){.search-content .search-input{font-size:1.953em}}@media (min-width: 80em){.search-content .search-input{font-size:2.441em}}.search-content.is--visible{display:block;visibility:visible}.search-content.is--visible::after{content:"";display:block}.search-content .results__found{margin-top:0.5em;font-size:.75em}.search-content .archive__item{margin-bottom:2em}@media (min-width: 64em){.search-content .archive__item{width:75%}}@media (min-width: 80em){.search-content .archive__item{width:50%}}.search-content .archive__item-title{margin-top:0}.search-content .archive__item-excerpt{margin-bottom:0}.ais-search-box{max-width:100% !important;margin-bottom:2em}.archive__item-title .ais-Highlight{color:#f60;font-style:normal;text-decoration:underline}.archive__item-excerpt .ais-Highlight{color:#f60;font-style:normal;font-weight:bold}div.highlighter-rouge,figure.highlight{position:relative;margin-bottom:1em;background:#263238;color:#eff;font-family:Monaco,Consolas,"Lucida Console",monospace;font-size:.75em;line-height:1.8;border-radius:4px}div.highlighter-rouge>pre,div.highlighter-rouge pre.highlight,figure.highlight>pre,figure.highlight pre.highlight{margin:0;padding:1em}.highlight table{margin-bottom:0;font-size:1em;border:0}.highlight table td{padding:0;width:calc(100% - 1em);border:0}.highlight table td.gutter,.highlight table td.rouge-gutter{padding-right:1em;width:1em;color:#b2ccd6;border-right:1px solid #b2ccd6;text-align:right}.highlight table td.code,.highlight table td.rouge-code{padding-left:1em}.highlight table pre{margin:0}.highlight pre{width:100%}.highlight .hll{background-color:#eff}.highlight .c{color:#b2ccd6}.highlight .err{color:#f07178}.highlight .k{color:#c792ea}.highlight .l{color:#f78c6c}.highlight .n{color:#eff}.highlight .o{color:#89ddff}.highlight .p{color:#eff}.highlight .cm{color:#b2ccd6}.highlight .cp{color:#b2ccd6}.highlight .c1{color:#b2ccd6}.highlight .cs{color:#b2ccd6}.highlight .gd{color:#f07178}.highlight .ge{font-style:italic}.highlight .gh{color:#eff;font-weight:bold}.highlight .gi{color:#c3e88d}.highlight .gp{color:#b2ccd6;font-weight:bold}.highlight .gs{font-weight:bold}.highlight .gu{color:#89ddff;font-weight:bold}.highlight .kc{color:#c792ea}.highlight .kd{color:#c792ea}.highlight .kn{color:#89ddff}.highlight .kp{color:#c792ea}.highlight .kr{color:#c792ea}.highlight .kt{color:#ffcb6b}.highlight .ld{color:#c3e88d}.highlight .m{color:#f78c6c}.highlight .s{color:#c3e88d}.highlight .na{color:#82aaff}.highlight .nb{color:#eff}.highlight .nc{color:#ffcb6b}.highlight .no{color:#f07178}.highlight .nd{color:#89ddff}.highlight .ni{color:#eff}.highlight .ne{color:#f07178}.highlight .nf{color:#82aaff}.highlight .nl{color:#eff}.highlight .nn{color:#ffcb6b}.highlight .nx{color:#82aaff}.highlight .py{color:#eff}.highlight .nt{color:#89ddff}.highlight .nv{color:#f07178}.highlight .ow{color:#89ddff}.highlight .w{color:#eff}.highlight .mf{color:#f78c6c}.highlight .mh{color:#f78c6c}.highlight .mi{color:#f78c6c}.highlight .mo{color:#f78c6c}.highlight .sb{color:#c3e88d}.highlight .sc{color:#eff}.highlight .sd{color:#b2ccd6}.highlight .s2{color:#c3e88d}.highlight .se{color:#f78c6c}.highlight .sh{color:#c3e88d}.highlight .si{color:#f78c6c}.highlight .sx{color:#c3e88d}.highlight .sr{color:#c3e88d}.highlight .s1{color:#c3e88d}.highlight .ss{color:#c3e88d}.highlight .bp{color:#eff}.highlight .vc{color:#f07178}.highlight .vg{color:#f07178}.highlight .vi{color:#f07178}.highlight .il{color:#f78c6c}.gist th,.gist td{border-bottom:0}.hidden,.is--hidden{display:none;visibility:hidden}.load{display:none}.transparent{opacity:0}.visually-hidden,.screen-reader-text,.screen-reader-text span,.screen-reader-shortcut{position:absolute !important;clip:rect(1px, 1px, 1px, 1px);height:1px !important;width:1px !important;border:0 !important;overflow:hidden}body:hover .visually-hidden a,body:hover .visually-hidden input,body:hover .visually-hidden button{display:none !important}.screen-reader-text:focus,.screen-reader-shortcut:focus{clip:auto !important;height:auto !important;width:auto !important;display:block;font-size:1em;font-weight:bold;padding:15px 23px 14px;background:#fff;z-index:100000;text-decoration:none;box-shadow:0 0 2px 2px rgba(0,0,0,0.6)}.skip-link{position:fixed;z-index:20;margin:0;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;white-space:nowrap}.skip-link li{height:0;width:0;list-style:none}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.task-list{padding:0}.task-list li{list-style-type:none}.task-list .task-list-item-checkbox{margin-right:0.5em;opacity:1}.task-list .task-list{margin-left:1em}.cf{clear:both}.wrapper{margin-left:auto;margin-right:auto;width:100%}.align-left{display:block;margin-left:auto;margin-right:auto}@media (min-width: 37.5em){.align-left{float:left;margin-right:1em}}.align-right{display:block;margin-left:auto;margin-right:auto}@media (min-width: 37.5em){.align-right{float:right;margin-left:1em}}.align-center{display:block;margin-left:auto;margin-right:auto}@media (min-width: 64em){.full{margin-right:-20.3389830508% !important}}.icon{display:inline-block;fill:currentColor;width:1em;height:1.1em;line-height:1;position:relative;top:-0.1em;vertical-align:middle}.social-icons .fas,.social-icons .fab,.social-icons .far,.social-icons .fal{color:#eaeaea}.social-icons .fa-behance,.social-icons .fa-behance-square{color:#1769ff}.social-icons .fa-bitbucket{color:#205081}.social-icons .fa-dribbble,.social-icons .fa-dribble-square{color:#ea4c89}.social-icons .fa-facebook,.social-icons .fa-facebook-square,.social-icons .fa-facebook-f{color:#3b5998}.social-icons .fa-flickr{color:#ff0084}.social-icons .fa-foursquare{color:#0072b1}.social-icons .fa-github,.social-icons .fa-github-alt,.social-icons .fa-github-square{color:inherit}.social-icons .fa-gitlab{color:#e24329}.social-icons .fa-instagram{color:#517fa4}.social-icons .fa-keybase{color:#ef7639}.social-icons .fa-lastfm,.social-icons .fa-lastfm-square{color:#d51007}.social-icons .fa-linkedin,.social-icons .fa-linkedin-in{color:#007bb6}.social-icons .fa-mastodon,.social-icons .fa-mastodon-square{color:#2b90d9}.social-icons .fa-pinterest,.social-icons .fa-pinterest-p,.social-icons .fa-pinterest-square{color:#cb2027}.social-icons .fa-reddit{color:#ff4500}.social-icons .fa-rss,.social-icons .fa-rss-square{color:#fa9b39}.social-icons .fa-soundcloud{color:#f30}.social-icons .fa-stack-exchange,.social-icons .fa-stack-overflow{color:#fe7a15}.social-icons .fa-tumblr,.social-icons .fa-tumblr-square{color:#32506d}.social-icons .fa-twitter,.social-icons .fa-twitter-square{color:#55acee}.social-icons .fa-vimeo,.social-icons .fa-vimeo-square,.social-icons .fa-vimeo-v{color:#1ab7ea}.social-icons .fa-vine{color:#00bf8f}.social-icons .fa-youtube{color:#b00}.social-icons .fa-xing,.social-icons .fa-xing-square{color:#006567}.navicon{position:relative;width:1.5rem;height:.25rem;background:#f60;margin:auto;-webkit-transition:0.3s;transition:0.3s}.navicon:before,.navicon:after{content:"";position:absolute;left:0;width:1.5rem;height:.25rem;background:#f60;-webkit-transition:0.3s;transition:0.3s}.navicon:before{top:-.5rem}.navicon:after{bottom:-.5rem}.close .navicon{background:transparent}.close .navicon:before,.close .navicon:after{-webkit-transform-origin:50% 50%;-ms-transform-origin:50% 50%;transform-origin:50% 50%;top:0;width:1.5rem}.close .navicon:before{-webkit-transform:rotate3d(0, 0, 1, 45deg);transform:rotate3d(0, 0, 1, 45deg)}.close .navicon:after{-webkit-transform:rotate3d(0, 0, 1, -45deg);transform:rotate3d(0, 0, 1, -45deg)}.greedy-nav__toggle:hover .navicon,.greedy-nav__toggle:hover .navicon:before,.greedy-nav__toggle:hover .navicon:after{background:#bf4d00}.greedy-nav__toggle:hover.close .navicon{background:transparent}@media (min-width: 64em){.sticky{clear:both;position:-webkit-sticky;position:sticky;top:2em}.sticky::after{clear:both;content:"";display:table}.sticky>*{display:block}}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.show-modal{overflow:hidden;position:relative}.show-modal:before{position:absolute;content:"";top:0;left:0;width:100%;height:100%;z-index:999;background-color:rgba(255,255,255,0.85)}.show-modal .modal{display:block}.modal{display:none;position:fixed;width:300px;top:50%;left:50%;margin-left:-150px;margin-top:-150px;min-height:0;z-index:9999;background:#fff;border:1px solid #51555d;border-radius:4px;box-shadow:0 1px 1px rgba(0,0,0,0.125)}.modal__title{margin:0;padding:0.5em 1em}.modal__supporting-text{padding:0 1em 0.5em 1em}.modal__actions{padding:0.5em 1em;border-top:1px solid #51555d}.footnote{color:#9ba1a6;text-decoration:none}.footnotes{color:#9ba1a6}.footnotes ol,.footnotes li,.footnotes p{margin-bottom:0;font-size:.75em}a.reversefootnote{color:#7a8288;text-decoration:none}a.reversefootnote:hover{text-decoration:underline}.required{color:#ee5f5b;font-weight:bold}.gsc-control-cse table,.gsc-control-cse tr,.gsc-control-cse td{border:0}.responsive-video-container{position:relative;margin-bottom:1em;padding-bottom:56.25%;height:0;overflow:hidden;max-width:100%}.responsive-video-container iframe,.responsive-video-container object,.responsive-video-container embed{position:absolute;top:0;left:0;width:100%;height:100%}:-webkit-full-screen-ancestor .masthead,:-webkit-full-screen-ancestor .page__footer{position:static}#main{clear:both;margin-left:auto;margin-right:auto;padding-left:1em;padding-right:1em;-webkit-animation:intro 0.3s both;animation:intro 0.3s both;max-width:100%;-webkit-animation-delay:0.15s;animation-delay:0.15s}#main::after{clear:both;content:"";display:table}@media (min-width: 80em){#main{max-width:1280px}}body{display:-webkit-box;display:-ms-flexbox;display:flex;min-height:100vh;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.initial-content,.search-content{flex:1 0 auto}@media (min-width: 64em){.page{float:right;width:calc(100% - 200px);padding-right:200px}}@media (min-width: 80em){.page{width:calc(100% - 300px);padding-right:300px}}.page .page__inner-wrap{float:left;margin-top:1em;margin-left:0;margin-right:0;width:100%;clear:both}.page .page__inner-wrap .page__content,.page .page__inner-wrap .page__meta,.page .page__inner-wrap .comment__date,.page .page__inner-wrap .page__share{position:relative;float:left;margin-left:0;margin-right:0;width:100%;clear:both}.page__title{margin-top:0;line-height:1}.page__title+.page__meta,.page__title+.comment__date{margin-top:-0.5em}.page__lead{font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:1.25em}.page__content h1 .header-link,.page__content h2 .header-link,.page__content h3 .header-link,.page__content h4 .header-link,.page__content h5 .header-link,.page__content h6 .header-link{position:relative;left:0.5em;opacity:0;font-size:0.8em;-webkit-transition:opacity 0.2s ease-in-out 0.1s;-moz-transition:opacity 0.2s ease-in-out 0.1s;-o-transition:opacity 0.2s ease-in-out 0.1s;transition:opacity 0.2s ease-in-out 0.1s}.page__content h1:hover .header-link,.page__content h2:hover .header-link,.page__content h3:hover .header-link,.page__content h4:hover .header-link,.page__content h5:hover .header-link,.page__content h6:hover .header-link{opacity:1}.page__content p,.page__content li,.page__content dl{font-size:1em}.page__content p{margin:0 0 1.3em}.page__content a:not(.btn):not(#goog-wm-sb):hover{text-decoration:underline}.page__content a:not(.btn):not(#goog-wm-sb):hover img{box-shadow:0 0 10px rgba(0,0,0,0.25)}.page__content dt{margin-top:1em;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-weight:bold}.page__content dd{margin-left:1em;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em}.page__content .small{font-size:.75em}.page__content blockquote+.small{margin-top:-1.5em;padding-left:1.25rem}.page__hero{position:relative;margin-bottom:2em;clear:both;-webkit-animation:intro 0.3s both;animation:intro 0.3s both;-webkit-animation-delay:0.25s;animation-delay:0.25s}.page__hero::after{clear:both;content:"";display:table}.page__hero--overlay{position:relative;margin-bottom:2em;padding:3em 0;clear:both;background-size:cover;background-repeat:no-repeat;background-position:center;-webkit-animation:intro 0.3s both;animation:intro 0.3s both;-webkit-animation-delay:0.25s;animation-delay:0.25s}.page__hero--overlay::after{clear:both;content:"";display:table}.page__hero--overlay a{color:#fff}.page__hero--overlay .wrapper{padding-left:1em;padding-right:1em}@media (min-width: 80em){.page__hero--overlay .wrapper{max-width:1280px}}.page__hero--overlay .page__title,.page__hero--overlay .page__meta,.page__hero--overlay .comment__date,.page__hero--overlay .page__lead{color:#fff;text-shadow:1px 1px 4px rgba(0,0,0,0.5)}.page__hero--overlay .btn,.page__hero--overlay #goog-wm-sb{color:#252a34}.page__hero--overlay .page__lead{max-width:768px}.page__hero--overlay .page__title{font-size:1.953em}@media (min-width: 37.5em){.page__hero--overlay .page__title{font-size:2.441em}}.page__hero-image{width:100%;height:auto;-ms-interpolation-mode:bicubic}.page__hero-caption{position:absolute;bottom:0;right:0;margin:0 auto;padding:2px 5px;color:#fff;font-family:sans-serif;font-size:.6875em;background:#000;text-align:right;z-index:5;opacity:0.5;border-radius:4px 0 0 0}@media (min-width: 64em){.page__hero-caption{padding:5px 10px}}.page__hero-caption a{color:#fff;text-decoration:none}.page__share{margin-top:2em;padding-top:1em;border-top:1px solid #51555d}@media (max-width: 37.5em){.page__share .btn span,.page__share #goog-wm-sb span{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}}.page__share-title{margin-bottom:10px;font-size:.75em;text-transform:uppercase}.page__meta,.comment__date{margin-top:2em;color:#eee;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em}.page__meta p,.comment__date p{margin:0}.page__meta a,.comment__date a{color:inherit}.page__meta-title{margin-bottom:10px;font-size:.75em;text-transform:uppercase}.page__taxonomy .sep{display:none}.page__taxonomy strong{margin-right:10px}.page__taxonomy-item{display:inline-block;margin-right:5px;margin-bottom:8px;padding:5px 10px;text-decoration:none;border:1px solid #3d4046;border-radius:4px}.page__taxonomy-item:hover{text-decoration:none;color:#fc9959}.taxonomy__section{margin-bottom:2em;padding-bottom:1em}.taxonomy__section:not(:last-child){border-bottom:solid 1px #51555d}.taxonomy__section .archive__item-title{margin-top:0}.taxonomy__section .archive__subtitle{clear:both;border:0}.taxonomy__section+.taxonomy__section{margin-top:2em}.taxonomy__title{margin-bottom:0.5em;color:#fff}.taxonomy__count{color:#fff}.taxonomy__index{display:grid;grid-column-gap:2em;grid-template-columns:repeat(2, 1fr);margin:1.414em 0;padding:0;font-size:0.75em;list-style:none}@media (min-width: 64em){.taxonomy__index{grid-template-columns:repeat(3, 1fr)}}.taxonomy__index a{display:-webkit-box;display:-ms-flexbox;display:flex;padding:0.25em 0;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;color:inherit;text-decoration:none;border-bottom:1px solid #51555d}.back-to-top{display:block;clear:both;color:#fff;font-size:0.6em;text-transform:uppercase;text-align:right;text-decoration:none}.page__comments{float:left;margin-left:0;margin-right:0;width:100%;clear:both}.page__comments-title{margin-top:2rem;margin-bottom:10px;padding-top:2rem;font-size:.75em;border-top:1px solid #51555d;text-transform:uppercase}.page__comments-form{-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.page__comments-form.disabled input,.page__comments-form.disabled button,.page__comments-form.disabled textarea,.page__comments-form.disabled label{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);box-shadow:none;opacity:0.65}.comment{clear:both;margin:1em 0}.comment::after{clear:both;content:"";display:table}.comment:not(:last-child){border-bottom:1px solid #51555d}.comment__avatar-wrapper{float:left;width:60px;height:60px}@media (min-width: 64em){.comment__avatar-wrapper{width:100px;height:100px}}.comment__avatar{width:40px;height:40px;border-radius:50%}@media (min-width: 64em){.comment__avatar{width:80px;height:80px;padding:5px;border:1px solid #51555d}}.comment__content-wrapper{float:right;width:calc(100% - 60px)}@media (min-width: 64em){.comment__content-wrapper{width:calc(100% - 100px)}}.comment__author{margin:0}.comment__author a{text-decoration:none}.comment__date{margin:0}.comment__date a{text-decoration:none}.page__related{clear:both;float:left;margin-top:2em;padding-top:1em;border-top:1px solid #51555d}.page__related::after{clear:both;content:"";display:table}@media (min-width: 64em){.page__related{float:right;width:calc(100% - 200px)}}@media (min-width: 80em){.page__related{width:calc(100% - 300px)}}.page__related a{color:inherit;text-decoration:none}.page__related-title{margin-bottom:10px;font-size:.75em;text-transform:uppercase}@media (min-width: 64em){.wide .page{padding-right:0}}@media (min-width: 80em){.wide .page{padding-right:0}}@media (min-width: 64em){.wide .page__related{padding-right:0}}@media (min-width: 80em){.wide .page__related{padding-right:0}}.archive{margin-top:1em;margin-bottom:2em}@media (min-width: 64em){.archive{float:right;width:calc(100% - 200px);padding-right:200px}}@media (min-width: 80em){.archive{width:calc(100% - 300px);padding-right:300px}}.archive__item{position:relative}.archive__item a{position:relative;z-index:10}.archive__item a[rel="permalink"]{position:static}.archive__subtitle{margin:1.414em 0 0;padding-bottom:0.5em;font-size:1em;color:#eee;border-bottom:1px solid #51555d}.archive__subtitle+.list__item .archive__item-title{margin-top:0.5em}.archive__item-title{margin-bottom:0.25em;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;line-height:initial;overflow:hidden;text-overflow:ellipsis}.archive__item-title a[rel="permalink"]::before{content:'';position:absolute;left:0;top:0;right:0;bottom:0}.archive__item-title a+a{opacity:0.5}.page__content .archive__item-title{margin-top:1em;border-bottom:none}.archive__item-excerpt{margin-top:0;font-size:.75em}.archive__item-excerpt+p{text-indent:0}.archive__item-excerpt a{position:relative}.archive__item-teaser{position:relative;border-radius:4px;overflow:hidden}.archive__item-teaser img{width:100%}.archive__item-caption{position:absolute;bottom:0;right:0;margin:0 auto;padding:2px 5px;color:#fff;font-family:sans-serif;font-size:.625em;background:#000;text-align:right;z-index:5;opacity:0.5;border-radius:4px 0 0 0}@media (min-width: 64em){.archive__item-caption{padding:5px 10px}}.archive__item-caption a{color:#fff;text-decoration:none}.list__item .page__meta,.list__item .comment__date{margin:0 0 4px;font-size:0.6em}@media (min-width: 64em){.archive .grid__wrapper{margin-right:-200px}}@media (min-width: 80em){.archive .grid__wrapper{margin-right:-300px}}.grid__item{margin-bottom:2em}@media (min-width: 37.5em){.grid__item{float:left;width:48.9795918367%}.grid__item:nth-child(2n+1){clear:both;margin-left:0}.grid__item:nth-child(2n+2){clear:none;margin-left:2.0408163265%}}@media (min-width: 48em){.grid__item{margin-left:0;margin-right:0;width:23.7288135593%}.grid__item:nth-child(2n+1){clear:none}.grid__item:nth-child(4n+1){clear:both}.grid__item:nth-child(4n+2){clear:none;margin-left:1.6949152542%}.grid__item:nth-child(4n+3){clear:none;margin-left:1.6949152542%}.grid__item:nth-child(4n+4){clear:none;margin-left:1.6949152542%}}.grid__item .page__meta,.grid__item .comment__date{margin:0 0 4px;font-size:0.6em}.grid__item .archive__item-title{margin-top:0.5em;font-size:1em}.grid__item .archive__item-excerpt{display:none}@media (min-width: 48em){.grid__item .archive__item-excerpt{display:block;font-size:.75em}}@media (min-width: 37.5em){.grid__item .archive__item-teaser{max-height:200px}}@media (min-width: 48em){.grid__item .archive__item-teaser{max-height:120px}}.feature__wrapper{clear:both;margin-bottom:2em;border-bottom:1px solid #51555d}.feature__wrapper::after{clear:both;content:"";display:table}.feature__wrapper .archive__item-title{margin-bottom:0}.feature__item{position:relative;margin-bottom:2em;font-size:1.125em}@media (min-width: 37.5em){.feature__item{float:left;margin-bottom:0;width:32.2033898305%}.feature__item:nth-child(3n+1){clear:both;margin-left:0}.feature__item:nth-child(3n+2){clear:none;margin-left:1.6949152542%}.feature__item:nth-child(3n+3){clear:none;margin-left:1.6949152542%}.feature__item .feature__item-teaser{max-height:200px;overflow:hidden}}.feature__item .archive__item-body{padding-left:1.6949152542%;padding-right:1.6949152542%}.feature__item a.btn::before,.feature__item a#goog-wm-sb::before{content:'';position:absolute;left:0;top:0;right:0;bottom:0}.feature__item--left{position:relative;float:left;margin-left:0;margin-right:0;width:100%;clear:both;font-size:1.125em}.feature__item--left .archive__item{float:left}.feature__item--left .archive__item-teaser{margin-bottom:2em}.feature__item--left a.btn::before,.feature__item--left a#goog-wm-sb::before{content:'';position:absolute;left:0;top:0;right:0;bottom:0}@media (min-width: 37.5em){.feature__item--left .archive__item-teaser{float:left;width:40.6779661017%}.feature__item--left .archive__item-body{float:right;padding-left:1.6949152542%;padding-right:1.6949152542%;width:57.6271186441%}}.feature__item--right{position:relative;float:left;margin-left:0;margin-right:0;width:100%;clear:both;font-size:1.125em}.feature__item--right .archive__item{float:left}.feature__item--right .archive__item-teaser{margin-bottom:2em}.feature__item--right a.btn::before,.feature__item--right a#goog-wm-sb::before{content:'';position:absolute;left:0;top:0;right:0;bottom:0}@media (min-width: 37.5em){.feature__item--right{text-align:right}.feature__item--right .archive__item-teaser{float:right;width:40.6779661017%}.feature__item--right .archive__item-body{float:left;width:57.6271186441%;padding-left:1.6949152542%;padding-right:1.6949152542%}}.feature__item--center{position:relative;float:left;margin-left:0;margin-right:0;width:100%;clear:both;font-size:1.125em}.feature__item--center .archive__item{float:left;width:100%}.feature__item--center .archive__item-teaser{margin-bottom:2em}.feature__item--center a.btn::before,.feature__item--center a#goog-wm-sb::before{content:'';position:absolute;left:0;top:0;right:0;bottom:0}@media (min-width: 37.5em){.feature__item--center{text-align:center}.feature__item--center .archive__item-teaser{margin:0 auto;width:40.6779661017%}.feature__item--center .archive__item-body{margin:0 auto;width:57.6271186441%}}.archive .feature__wrapper .archive__item-title{margin-top:0.25em;font-size:1em}.archive .feature__item,.archive .feature__item--left,.archive .feature__item--center,.archive .feature__item--right{font-size:1em}@media (min-width: 64em){.wide .archive{padding-right:0}}@media (min-width: 80em){.wide .archive{padding-right:0}}.layout--single .feature__wrapper{display:inline-block}.sidebar{clear:both}.sidebar::after{clear:both;content:"";display:table}@media (min-width: 64em){.sidebar{float:left;width:calc(200px - 1em);opacity:0.75;-webkit-transition:opacity 0.2s ease-in-out;transition:opacity 0.2s ease-in-out}.sidebar:hover{opacity:1}.sidebar.sticky{overflow-y:auto;max-height:calc(100vh - 2em - 2em)}}@media (min-width: 80em){.sidebar{width:calc(300px - 1em)}}.sidebar>*{margin-top:1em;margin-bottom:1em}.sidebar h2,.sidebar h3,.sidebar h4,.sidebar h5,.sidebar h6{margin-bottom:0;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif}.sidebar p,.sidebar li{font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em;line-height:1.5}.sidebar img{width:100%}.sidebar img.emoji{width:20px;height:20px}.sidebar__right{margin-bottom:1em}@media (min-width: 64em){.sidebar__right{position:absolute;top:0;right:0;width:200px;margin-right:-200px;padding-left:1em;z-index:10}.sidebar__right.sticky{clear:both;position:-webkit-sticky;position:sticky;top:2em;float:right}.sidebar__right.sticky::after{clear:both;content:"";display:table}}@media (min-width: 80em){.sidebar__right{width:300px;margin-right:-300px}}@media (min-width: 64em){.splash .sidebar__right{position:relative;float:right;margin-right:0}}@media (min-width: 80em){.splash .sidebar__right{margin-right:0}}.author__avatar{display:table-cell;vertical-align:top;width:36px;height:36px}@media (min-width: 64em){.author__avatar{display:block;width:auto;height:auto}}.author__avatar img{max-width:110px;border-radius:50%}@media (min-width: 64em){.author__avatar img{padding:5px;border:1px solid #51555d}}.author__content{display:table-cell;vertical-align:top;padding-left:15px;padding-right:25px;line-height:1}@media (min-width: 64em){.author__content{display:block;width:100%;padding-left:0;padding-right:0}}.author__content a{color:inherit;text-decoration:none}.author__name{margin:0}@media (min-width: 64em){.author__name{margin-top:10px;margin-bottom:10px}}.sidebar .author__name{font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:1em}.author__bio{margin:0}@media (min-width: 64em){.author__bio{margin-top:10px;margin-bottom:20px}}.author__urls-wrapper{position:relative;display:table-cell;vertical-align:middle;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;z-index:20;cursor:pointer}.author__urls-wrapper li:last-child a{margin-bottom:0}.author__urls-wrapper .author__urls span.label{padding-left:5px}@media (min-width: 64em){.author__urls-wrapper{display:block}}.author__urls-wrapper button{position:relative;margin-bottom:0}@supports (pointer-events: none){.author__urls-wrapper button:before{content:'';position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none}}.author__urls-wrapper button.open:before{pointer-events:auto}@media (min-width: 64em){.author__urls-wrapper button{display:none}}.author__urls{display:none;position:absolute;right:0;margin-top:15px;padding:10px;list-style-type:none;border:1px solid #51555d;border-radius:4px;background:#252a34;box-shadow:0 2px 4px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12);cursor:default}.author__urls.is--visible{display:block}@media (min-width: 64em){.author__urls{display:block;position:relative;margin:0;padding:0;border:0;background:transparent;box-shadow:none}}.author__urls:before{display:block;content:"";position:absolute;top:-11px;left:calc(50% - 10px);width:0;border-style:solid;border-width:0 10px 10px;border-color:#51555d transparent;z-index:0}@media (min-width: 64em){.author__urls:before{display:none}}.author__urls:after{display:block;content:"";position:absolute;top:-10px;left:calc(50% - 10px);width:0;border-style:solid;border-width:0 10px 10px;border-color:#252a34 transparent;z-index:1}@media (min-width: 64em){.author__urls:after{display:none}}.author__urls ul{padding:10px;list-style-type:none}.author__urls li{white-space:nowrap}.author__urls a{display:block;margin-bottom:5px;padding-right:5px;padding-top:2px;padding-bottom:2px;color:inherit;font-size:1em;text-decoration:none}.author__urls a:hover{text-decoration:underline}.wide .sidebar__right{margin-bottom:1em}@media (min-width: 64em){.wide .sidebar__right{position:initial;top:initial;right:initial;width:initial;margin-right:initial;padding-left:initial;z-index:initial}.wide .sidebar__right.sticky{float:none}}@media (min-width: 80em){.wide .sidebar__right{width:initial;margin-right:initial}}@media print{[hidden]{display:none}*{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}html{margin:0;padding:0;min-height:auto !important;font-size:16px}body{margin:0 auto;background:#fff !important;color:#000 !important;font-size:1rem;line-height:1.5;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}h1,h2,h3,h4,h5,h6{color:#000;line-height:1.2;margin-bottom:0.75rem;margin-top:0}h1{font-size:2.5rem}h2{font-size:2rem}h3{font-size:1.75rem}h4{font-size:1.5rem}h5{font-size:1.25rem}h6{font-size:1rem}a,a:visited{color:#000;text-decoration:underline;word-wrap:break-word}table{border-collapse:collapse}thead{display:table-header-group}table,th,td{border-bottom:1px solid #000}td,th{padding:8px 16px}img{border:0;display:block;max-width:100% !important;vertical-align:middle}hr{border:0;border-bottom:2px solid #bbb;height:0;margin:2.25rem 0;padding:0}dt{font-weight:bold}dd{margin:0;margin-bottom:0.75rem}abbr[title],acronym[title]{border:0;text-decoration:none}table,blockquote,pre,code,figure,li,hr,ul,ol,a,tr{page-break-inside:avoid}h2,h3,h4,p,a{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid;page-break-inside:avoid}h1+p,h2+p,h3+p{page-break-before:avoid}img{page-break-after:auto;page-break-before:auto;page-break-inside:avoid}pre{white-space:pre-wrap !important;word-wrap:break-word}a[href^='http://']:after,a[href^='https://']:after,a[href^='ftp://']:after{content:" (" attr(href) ")";font-size:80%}abbr[title]:after,acronym[title]:after{content:" (" attr(title) ")"}#main{max-width:100%}.page{margin:0;padding:0;width:100%}.page-break,.page-break-before{page-break-before:always}.page-break-after{page-break-after:always}.no-print{display:none}a.no-reformat:after{content:''}abbr[title].no-reformat:after,acronym[title].no-reformat:after{content:''}.page__hero-caption{color:#000 !important;background:#fff !important;opacity:1}.page__hero-caption a{color:#000 !important}.masthead,.toc,.page__share,.page__related,.pagination,.ads,.page__footer,.page__comments-form,.author__avatar,.author__content,.author__urls-wrapper,.nav__list,.sidebar,.adsbygoogle{display:none !important;height:1px !important}}.pagination li a.disabled{color:rgba(241,241,241,0.8)}.sidebar{opacity:1}.bigfoot-footnote__button{position:relative;z-index:5;top:-.1em;box-sizing:border-box;-moz-box-sizing:border-box;display:inline-block;padding:.35em;margin:0 .1em 0 .2em;border:none;border-radius:.3em;cursor:pointer;background-color:rgba(0,179,134,0.2);backface-visibility:hidden;font-size:1rem;line-height:0;vertical-align:middle;text-decoration:none;-webkit-font-smoothing:antialiased;transition-property:background-color;transition-duration:.25s}.bigfoot-footnote__button:hover,.bigfoot-footnote__button:focus{outline:none;background-color:rgba(0,179,134,0.5)}.bigfoot-footnote__button:active{background-color:rgba(0,179,134,0.5)}.bigfoot-footnote__button.is-active{background-color:#00b386;transition-delay:.1s}.bigfoot-footnote__button:after{content:'';display:table;clear:both}.bigfoot-footnote__button__circle{display:inline-block;width:.25em;height:.25em;margin-right:.25em;float:left}.bigfoot-footnote__button__circle:last-child{margin-right:0}.bigfoot-footnote__container{display:inline-block;position:relative;text-indent:0}@media not print{.footnote-print-only{display:none !important}}@media print{.bigfoot-footnote,.bigfoot-footnote__button{display:none !important}}.bigfoot-footnote{position:absolute;z-index:10;top:0;left:0;display:inline-block;box-sizing:border-box;max-width:90%;margin:1.9692388156em 0;background:#1a534d;opacity:0;border-radius:.5em;border:1px solid #c3c3c3;box-shadow:0px 0px 8px rgba(0,0,0,0.3);line-height:0;transition-property:opacity,transform;transition-duration:.25s;transition-timing-function:ease;transform:scale(0.1) translateZ(0);transform-origin:50% 0}.bigfoot-footnote.is-positioned-top{top:auto;bottom:0}.bigfoot-footnote.is-active{transform:scale(1) translateZ(0);opacity:.99}.bigfoot-footnote.is-bottom-fixed{position:fixed;bottom:0;top:auto;left:0;right:auto;transform:translateY(100%);width:100%;margin:0;border-radius:0;opacity:1;border-width:1px 0 0;transition:transform 0.3s ease}.bigfoot-footnote.is-bottom-fixed.is-active{transform:translateY(0)}.bigfoot-footnote.is-bottom-fixed .bigfoot-footnote__wrapper{margin:0 0 0 50%;transform:translateX(-50%);max-width:100%}.bigfoot-footnote.is-bottom-fixed .bigfoot-footnote__wrapper,.bigfoot-footnote.is-bottom-fixed .bigfoot-footnote__content{border-radius:0}.bigfoot-footnote.is-bottom-fixed .bigfoot-footnote__tooltip{display:none}.bigfoot-footnote.is-scrollable:after{content:'';position:absolute;bottom:.3375em;left:.3375em;z-index:14;display:block;height:.78125em;width:.625em;background-image:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTJweCIgaGVpZ2h0PSIxNXB4IiB2aWV3Qm94PSIwIDAgMTIgMTUiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pbllNaW4iPgogICAgPGcgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9IkFycm93IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxLjAwMDAwMCwgMS4wMDAwMDApIiBzdHJva2U9ImJsYWNrIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiPgogICAgICAgICAgICA8cGF0aCBkPSJNNSwwIEw1LDExLjUiIGlkPSJMaW5lIj48L3BhdGg+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0wLjUsNy41IEw1LjAyNzY5Mjc5LDEyLjAyNzY5MjgiIGlkPSJMaW5lIj48L3BhdGg+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik00LjUsNy41IEw5LjAyNzY5Mjc5LDEyLjAyNzY5MjgiIGlkPSJMaW5lLTIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDcuMDAwMDAwLCAxMC4wMDAwMDApIHNjYWxlKC0xLCAxKSB0cmFuc2xhdGUoLTcuMDAwMDAwLCAtMTAuMDAwMDAwKSAiPjwvcGF0aD4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPgo=");background-size:cover;opacity:.1;transition-properties:opacity;transition-duration:.25s;transition-timing-function:ease}.bigfoot-footnote.is-scrollable .bigfoot-footnote__wrapper:before,.bigfoot-footnote.is-scrollable .bigfoot-footnote__wrapper:after{content:'';position:absolute;width:100%;z-index:12;left:0}.bigfoot-footnote.is-scrollable .bigfoot-footnote__wrapper:before{top:-1px;height:1.1em;border-radius:.5em .5em 0 0;background-image:linear-gradient(to bottom, #1a534d 50%, rgba(26,83,77,0) 100%)}.bigfoot-footnote.is-scrollable .bigfoot-footnote__wrapper:after{bottom:-1px;height:1.2em;border-radius:0 0 .5em .5em;background-image:linear-gradient(to top, #1a534d 50%, rgba(26,83,77,0) 100%)}.bigfoot-footnote.is-scrollable ::-webkit-scrollbar{display:none}.bigfoot-footnote.is-fully-scrolled:after,.bigfoot-footnote.is-fully-scrolled:before{opacity:0;transition-delay:0}.bigfoot-footnote__wrapper{position:relative;z-index:14;width:35em;display:inline-block;box-sizing:inherit;overflow:hidden;margin:0;background-color:#1a534d;border-radius:.5em;line-height:0}.bigfoot-footnote__content{position:relative;z-index:8;display:inline-block;max-height:20em;padding:1.1em 1.3em 1.2em;box-sizing:inherit;overflow:auto;-webkit-overflow-scrolling:touch;background:#1a534d;border-radius:.5em;-webkit-font-smoothing:subpixel-antialiased;line-height:normal}.bigfoot-footnote__content img{max-width:100%}.bigfoot-footnote__content *:last-child{margin-bottom:0 !important}.bigfoot-footnote__content *:first-child{margin-top:0 !important}.bigfoot-footnote__tooltip{position:absolute;z-index:12;box-sizing:border-box;margin-left:-.65em;width:1.3em;height:1.3em;transform:rotate(45deg);background:#1a534d;border:1px solid #c3c3c3;box-shadow:0px 0px 8px rgba(0,0,0,0.3);border-top-left-radius:0}.is-positioned-bottom .bigfoot-footnote__tooltip{top:-.65em}.is-positioned-top .bigfoot-footnote__tooltip{bottom:-.65em}.bigfoot-footnote__button{position:relative;height:.95em;width:1.5em;border-radius:.475em}.bigfoot-footnote__button:after{content:attr(data-footnote-number);position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);display:block;font-size:.57em;font-weight:bold;color:#fca66d;transition:color .25s ease}.bigfoot-footnote__button:hover:after,.bigfoot-footnote__button.is-active:after{color:white}.bigfoot-footnote__button__circle{display:none}.bigfoot-footnote{position:absolute;z-index:10;top:0;left:0;display:inline-block;box-sizing:border-box;max-width:90%;margin:1.9692388156em 0;background:#1a534d;opacity:0;border-radius:.5em;border:1px solid #c3c3c3;box-shadow:0px 0px 8px rgba(0,0,0,0.3);line-height:0;transition-property:opacity,transform;transition-duration:.25s;transition-timing-function:ease;transform:scale(0.1) translateZ(0);transform-origin:50% 0}.bigfoot-footnote.is-positioned-top{top:auto;bottom:0}.bigfoot-footnote.is-active{transform:scale(1) translateZ(0);opacity:.99}.bigfoot-footnote.is-bottom-fixed{position:fixed;bottom:0;top:auto;left:0;right:auto;transform:translateY(100%);width:100%;margin:0;border-radius:0;opacity:1;border-width:1px 0 0;transition:transform 0.3s ease}.bigfoot-footnote.is-bottom-fixed.is-active{transform:translateY(0)}.bigfoot-footnote.is-bottom-fixed .bigfoot-footnote__wrapper{margin:0 0 0 50%;transform:translateX(-50%);max-width:100%}.bigfoot-footnote.is-bottom-fixed .bigfoot-footnote__wrapper,.bigfoot-footnote.is-bottom-fixed .bigfoot-footnote__content{border-radius:0}.bigfoot-footnote.is-bottom-fixed .bigfoot-footnote__tooltip{display:none}.bigfoot-footnote.is-scrollable:after{content:'';position:absolute;bottom:.3375em;left:.3375em;z-index:14;display:block;height:.78125em;width:.625em;background-image:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTJweCIgaGVpZ2h0PSIxNXB4IiB2aWV3Qm94PSIwIDAgMTIgMTUiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pbllNaW4iPgogICAgPGcgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9IkFycm93IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxLjAwMDAwMCwgMS4wMDAwMDApIiBzdHJva2U9ImJsYWNrIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiPgogICAgICAgICAgICA8cGF0aCBkPSJNNSwwIEw1LDExLjUiIGlkPSJMaW5lIj48L3BhdGg+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0wLjUsNy41IEw1LjAyNzY5Mjc5LDEyLjAyNzY5MjgiIGlkPSJMaW5lIj48L3BhdGg+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik00LjUsNy41IEw5LjAyNzY5Mjc5LDEyLjAyNzY5MjgiIGlkPSJMaW5lLTIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDcuMDAwMDAwLCAxMC4wMDAwMDApIHNjYWxlKC0xLCAxKSB0cmFuc2xhdGUoLTcuMDAwMDAwLCAtMTAuMDAwMDAwKSAiPjwvcGF0aD4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPgo=");background-size:cover;opacity:.1;transition-properties:opacity;transition-duration:.25s;transition-timing-function:ease}.bigfoot-footnote.is-scrollable .bigfoot-footnote__wrapper:before,.bigfoot-footnote.is-scrollable .bigfoot-footnote__wrapper:after{content:'';position:absolute;width:100%;z-index:12;left:0}.bigfoot-footnote.is-scrollable .bigfoot-footnote__wrapper:before{top:-1px;height:1.1em;border-radius:.5em .5em 0 0;background-image:linear-gradient(to bottom, #1a534d 50%, rgba(26,83,77,0) 100%)}.bigfoot-footnote.is-scrollable .bigfoot-footnote__wrapper:after{bottom:-1px;height:1.2em;border-radius:0 0 .5em .5em;background-image:linear-gradient(to top, #1a534d 50%, rgba(26,83,77,0) 100%)}.bigfoot-footnote.is-scrollable ::-webkit-scrollbar{display:none}.bigfoot-footnote.is-fully-scrolled:after,.bigfoot-footnote.is-fully-scrolled:before{opacity:0;transition-delay:0}.bigfoot-footnote__wrapper{position:relative;z-index:14;width:35em;display:inline-block;box-sizing:inherit;overflow:hidden;margin:0;background-color:#1a534d;border-radius:.5em;line-height:0}.bigfoot-footnote__content{position:relative;z-index:8;display:inline-block;max-height:20em;padding:1.1em 1.3em 1.2em;box-sizing:inherit;overflow:auto;-webkit-overflow-scrolling:touch;background:#1a534d;border-radius:.5em;-webkit-font-smoothing:subpixel-antialiased;line-height:normal}.bigfoot-footnote__content img{max-width:100%}.bigfoot-footnote__content *:last-child{margin-bottom:0 !important}.bigfoot-footnote__content *:first-child{margin-top:0 !important}.bigfoot-footnote__tooltip{position:absolute;z-index:12;box-sizing:border-box;margin-left:-.65em;width:1.3em;height:1.3em;transform:rotate(45deg);background:#1a534d;border:1px solid #c3c3c3;box-shadow:0px 0px 8px rgba(0,0,0,0.3);border-top-left-radius:0}.is-positioned-bottom .bigfoot-footnote__tooltip{top:-.65em}.is-positioned-top .bigfoot-footnote__tooltip{bottom:-.65em}.greedy-nav a:focus,div:focus,.search__toggle a:focus,button:focus,.taxonomy__index a:focus,a.back-to-top:focus{outline:.2rem solid;outline-offset:.2rem;outline-color:#00D19D;box-shadow:0 0 0 .3rem #f0f0f0}.author__urls a:focus,.page__taxonomy-item:focus,.pagination li a:focus,.pagination--pager:focus,.archive__item a:focus,.toc__menu a:focus,a.btn:focus,a#goog-wm-sb:focus{outline:solid 3px;outline-offset:-3px;outline-color:#00D19D}h1:focus,h2:focus,h3:focus,h4:focus,h5:focus,h6:focus{outline:solid 3px;outline-offset:-3px;outline-color:#00D19D}.archive__item a[rel="permalink"]{position:relative}h2{padding-bottom:0em;border-bottom:none}.notice{margin:2em 0 !important;padding:1em;color:#1b1b1b;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em !important;text-indent:initial;background-color:#d8d9da;border-radius:4px;box-shadow:0 1px 1px rgba(61,65,68,0.25)}.notice h4{margin-top:0 !important;margin-bottom:0.75em}.page__content .notice h4{margin-bottom:0;font-size:1em}.notice p:last-child{margin-bottom:0 !important}.notice h4+p{margin-top:0;padding-top:0}.notice a{color:#373b3d}.notice a:hover{color:#252729}.notice code{background-color:#f5f6f6}.notice pre code{background-color:inherit}.notice ul:last-child{margin-bottom:0}.notice--primary{margin:2em 0 !important;padding:1em;color:#1b1b1b;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em !important;text-indent:initial;background-color:#ffe0cc;border-radius:4px;box-shadow:0 1px 1px rgba(255,102,0,0.25)}.notice--primary h4{margin-top:0 !important;margin-bottom:0.75em}.page__content .notice--primary h4{margin-bottom:0;font-size:1em}.notice--primary p:last-child{margin-bottom:0 !important}.notice--primary h4+p{margin-top:0;padding-top:0}.notice--primary a{color:#e65c00}.notice--primary a:hover{color:#993d00}.notice--primary code{background-color:#fff7f2}.notice--primary pre code{background-color:inherit}.notice--primary ul:last-child{margin-bottom:0}.notice--info{margin:2em 0 !important;padding:1em;color:#1b1b1b;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em !important;text-indent:initial;background-color:#d8ebf1;border-radius:4px;box-shadow:0 1px 1px rgba(59,156,186,0.25)}.notice--info h4{margin-top:0 !important;margin-bottom:0.75em}.page__content .notice--info h4{margin-bottom:0;font-size:1em}.notice--info p:last-child{margin-bottom:0 !important}.notice--info h4+p{margin-top:0;padding-top:0}.notice--info a{color:#358ca7}.notice--info a:hover{color:#235e70}.notice--info code{background-color:#f5fafc}.notice--info pre code{background-color:inherit}.notice--info ul:last-child{margin-bottom:0}.notice--warning{margin:2em 0 !important;padding:1em;color:#1b1b1b;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em !important;text-indent:initial;background-color:#f7e5cd;border-radius:4px;box-shadow:0 1px 1px rgba(214,127,5,0.25)}.notice--warning h4{margin-top:0 !important;margin-bottom:0.75em}.page__content .notice--warning h4{margin-bottom:0;font-size:1em}.notice--warning p:last-child{margin-bottom:0 !important}.notice--warning h4+p{margin-top:0;padding-top:0}.notice--warning a{color:#c17205}.notice--warning a:hover{color:#804c03}.notice--warning code{background-color:#fdf9f3}.notice--warning pre code{background-color:inherit}.notice--warning ul:last-child{margin-bottom:0}.notice--success{margin:2em 0 !important;padding:1em;color:#1b1b1b;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em !important;text-indent:initial;background-color:#d9edd9;border-radius:4px;box-shadow:0 1px 1px rgba(63,166,63,0.25)}.notice--success h4{margin-top:0 !important;margin-bottom:0.75em}.page__content .notice--success h4{margin-bottom:0;font-size:1em}.notice--success p:last-child{margin-bottom:0 !important}.notice--success h4+p{margin-top:0;padding-top:0}.notice--success a{color:#399539}.notice--success a:hover{color:#266426}.notice--success code{background-color:#f5fbf5}.notice--success pre code{background-color:inherit}.notice--success ul:last-child{margin-bottom:0}.notice--danger{margin:2em 0 !important;padding:1em;color:#1b1b1b;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em !important;text-indent:initial;background-color:#fcdfde;border-radius:4px;box-shadow:0 1px 1px rgba(238,95,91,0.25)}.notice--danger h4{margin-top:0 !important;margin-bottom:0.75em}.page__content .notice--danger h4{margin-bottom:0;font-size:1em}.notice--danger p:last-child{margin-bottom:0 !important}.notice--danger h4+p{margin-top:0;padding-top:0}.notice--danger a{color:#d65652}.notice--danger a:hover{color:#8f3937}.notice--danger code{background-color:#fef7f7}.notice--danger pre code{background-color:inherit}.notice--danger ul:last-child{margin-bottom:0}.page__content h1 .header-link:focus,.page__content h2 .header-link:focus,.page__content h3 .header-link:focus,.page__content h4 .header-link:focus,.page__content h5 .header-link:focus,.page__content h6 .header-link:focus{opacity:unset}a:focus,button:focus,.bigfoot-footnote__button:focus,summary:focus{outline:0.2rem solid #00D19D;box-shadow:0 0 0 .3rem #f0f0f0} diff --git a/assets/css/main2.css b/assets/css/main2.css new file mode 100644 index 000000000..49498c554 --- /dev/null +++ b/assets/css/main2.css @@ -0,0 +1,5 @@ +.author__urls.social-icons .svg-inline--fa,.author__urls.social-icons .svg-inline--fab,.page__footer-follow .social-icons .svg-inline--fa{color:inherit}.ais-search-box .ais-search-box--input{background-color:#d7d7d7}.audience{color:#005a42;font-weight:bold;display:block}.wiki-flex{display:flex;flex-flow:row wrap;justify-content:space-between;align-items:center}.wiki-flex-item{flex:1;text-align:center}.wiki-folder-grid{display:flex;flex-flow:row wrap;justify-content:flex-start;align-items:center}.wiki-folder-grid-thirds{flex:none;flex-basis:calc(100%/3);text-align:center;padding:.5em .5em .5em .5em}.backlink-box{background:#e3e3e3;padding:1em;border-radius:4px;border-width:1px;border-style:solid;border-color:#cbcbcb;position:relative}.backlink-box:hover{box-shadow:0 0 0 0.25rem #a3470a}.backlink-box a::after{content:'';position:absolute;top:0;right:0;bottom:0;left:0}.backlink-box a{text-decoration:underline}.backlink-box a:focus{text-decoration:underline}.backlink-box:focus-within{box-shadow:0 0 0 0.25rem #a3470a}.backlink-box:focus-within a:focus{text-decoration:underline}details summary{outline:2px solid #cbcbcb;cursor:pointer;padding:.5rem 1rem}details summary>*{display:inline}details>div{border:2px solid #cbcbcb;margin-top:0;padding:1rem}details{padding:.5rem}summary:hover{box-shadow:0 0 0 0.35rem #005a42}.list-unstyled{list-style:none;padding:0}progress{-webkit-appearance:none}::-webkit-progress-value{background-color:#007053}::-moz-progress-bar{background-color:#007053}.bigfoot-footnote{background:#d5e5e1}.bigfoot-footnote__wrapper{background-color:#d5e5e1}.bigfoot-footnote__content{background:#d5e5e1}.bigfoot-footnote__tooltip{background:#d5e5e1}.bigfoot-footnote__button::after{color:#C24E00}.greedy-nav a:focus,div:focus,.search__toggle a:focus,button:focus,.taxonomy__index a:focus,a.back-to-top:focus{outline:.2rem solid;outline-offset:.2rem;outline-color:#007053;box-shadow:0 0 0 .3rem #f0f0f0}h1,h2,h3,h4,h5,h6{color:#007053}.footnote{color:#424242 !important;text-decoration:none}.footnotes{color:#424242 !important}/*! + * Minimal Mistakes Jekyll Theme 4.17.2 by Michael Rose + * Copyright 2013-2019 Michael Rose - mademistakes.com | @mmistakes + * Licensed under MIT (https://github.com/mmistakes/minimal-mistakes/blob/master/LICENSE) +*/.mfp-counter{font-family:Georgia,Times,serif}.mfp-bg{top:0;left:0;width:100%;height:100%;z-index:1042;overflow:hidden;position:fixed;background:#000;opacity:.8;filter:alpha(opacity=80)}.mfp-wrap{top:0;left:0;width:100%;height:100%;z-index:1043;position:fixed;outline:none !important;-webkit-backface-visibility:hidden}.mfp-container{text-align:center;position:absolute;width:100%;height:100%;left:0;top:0;padding:0 8px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.mfp-container:before{content:'';display:inline-block;height:100%;vertical-align:middle}.mfp-align-top .mfp-container:before{display:none}.mfp-content{position:relative;display:inline-block;vertical-align:middle;margin:0 auto;text-align:left;z-index:1045}.mfp-inline-holder .mfp-content,.mfp-ajax-holder .mfp-content{width:100%;cursor:auto}.mfp-ajax-cur{cursor:progress}.mfp-zoom-out-cur,.mfp-zoom-out-cur .mfp-image-holder .mfp-close{cursor:-moz-zoom-out;cursor:-webkit-zoom-out;cursor:zoom-out}.mfp-zoom{cursor:pointer;cursor:-webkit-zoom-in;cursor:-moz-zoom-in;cursor:zoom-in}.mfp-auto-cursor .mfp-content{cursor:auto}.mfp-close,.mfp-arrow,.mfp-preloader,.mfp-counter{-webkit-user-select:none;-moz-user-select:none;user-select:none}.mfp-loading.mfp-figure{display:none}.mfp-hide{display:none !important}.mfp-preloader{color:#ccc;position:absolute;top:50%;width:auto;text-align:center;margin-top:-0.8em;left:8px;right:8px;z-index:1044}.mfp-preloader a{color:#ccc}.mfp-preloader a:hover{color:#fff}.mfp-s-ready .mfp-preloader{display:none}.mfp-s-error .mfp-content{display:none}button.mfp-close,button.mfp-arrow{overflow:visible;cursor:pointer;background:transparent;border:0;-webkit-appearance:none;display:block;outline:none;padding:0;z-index:1046;-webkit-box-shadow:none;box-shadow:none}button::-moz-focus-inner{padding:0;border:0}.mfp-close{width:44px;height:44px;line-height:44px;position:absolute;right:0;top:0;text-decoration:none;text-align:center;opacity:1;filter:alpha(opacity=100);padding:0 0 18px 10px;color:#fff;font-style:normal;font-size:28px;font-family:Georgia,Times,serif}.mfp-close:hover,.mfp-close:focus{opacity:1;filter:alpha(opacity=100)}.mfp-close:active{top:1px}.mfp-close-btn-in .mfp-close{color:#fff}.mfp-image-holder .mfp-close,.mfp-iframe-holder .mfp-close{color:#fff;right:-6px;text-align:right;padding-right:6px;width:100%}.mfp-counter{position:absolute;top:0;right:0;color:#ccc;font-size:12px;line-height:18px}.mfp-arrow{position:absolute;opacity:1;filter:alpha(opacity=100);margin:0;top:50%;margin-top:-55px;padding:0;width:90px;height:110px;-webkit-tap-highlight-color:transparent}.mfp-arrow:active{margin-top:-54px}.mfp-arrow:hover,.mfp-arrow:focus{opacity:1;filter:alpha(opacity=100)}.mfp-arrow:before,.mfp-arrow:after,.mfp-arrow .mfp-b,.mfp-arrow .mfp-a{content:'';display:block;width:0;height:0;position:absolute;left:0;top:0;margin-top:35px;margin-left:35px;border:medium inset transparent}.mfp-arrow:after,.mfp-arrow .mfp-a{border-top-width:13px;border-bottom-width:13px;top:8px}.mfp-arrow:before,.mfp-arrow .mfp-b{border-top-width:21px;border-bottom-width:21px;opacity:0.7}.mfp-arrow-left{left:0}.mfp-arrow-left:after,.mfp-arrow-left .mfp-a{border-right:17px solid #fff;margin-left:31px}.mfp-arrow-left:before,.mfp-arrow-left .mfp-b{margin-left:25px;border-right:27px solid #fff}.mfp-arrow-right{right:0}.mfp-arrow-right:after,.mfp-arrow-right .mfp-a{border-left:17px solid #fff;margin-left:39px}.mfp-arrow-right:before,.mfp-arrow-right .mfp-b{border-left:27px solid #fff}.mfp-iframe-holder{padding-top:40px;padding-bottom:40px}.mfp-iframe-holder .mfp-content{line-height:0;width:100%;max-width:900px}.mfp-iframe-holder .mfp-close{top:-40px}.mfp-iframe-scaler{width:100%;height:0;overflow:hidden;padding-top:56.25%}.mfp-iframe-scaler iframe{position:absolute;display:block;top:0;left:0;width:100%;height:100%;box-shadow:0 0 8px rgba(0,0,0,0.6);background:#000}img.mfp-img{width:auto;max-width:100%;height:auto;display:block;line-height:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:40px 0 40px;margin:0 auto}.mfp-figure{line-height:0}.mfp-figure:after{content:'';position:absolute;left:0;top:40px;bottom:40px;display:block;right:0;width:auto;height:auto;z-index:-1;box-shadow:0 0 8px rgba(0,0,0,0.6);background:#444}.mfp-figure small{color:#bdbdbd;display:block;font-size:12px;line-height:14px}.mfp-figure figure{margin:0}.mfp-figure figcaption{margin-top:0;margin-bottom:0}.mfp-bottom-bar{margin-top:-36px;position:absolute;top:100%;left:0;width:100%;cursor:auto}.mfp-title{text-align:left;line-height:18px;color:#f3f3f3;word-wrap:break-word;padding-right:36px}.mfp-image-holder .mfp-content{max-width:100%}.mfp-gallery .mfp-image-holder .mfp-figure{cursor:pointer}@media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px){.mfp-img-mobile .mfp-image-holder{padding-left:0;padding-right:0}.mfp-img-mobile img.mfp-img{padding:0}.mfp-img-mobile .mfp-figure:after{top:0;bottom:0}.mfp-img-mobile .mfp-figure small{display:inline;margin-left:5px}.mfp-img-mobile .mfp-bottom-bar{background:rgba(0,0,0,0.6);bottom:0;margin:0;top:auto;padding:3px 5px;position:fixed;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.mfp-img-mobile .mfp-bottom-bar:empty{padding:0}.mfp-img-mobile .mfp-counter{right:5px;top:3px}.mfp-img-mobile .mfp-close{top:0;right:0;width:35px;height:35px;line-height:35px;background:rgba(0,0,0,0.6);position:fixed;text-align:center;padding:0}}@media all and (max-width: 900px){.mfp-arrow{-webkit-transform:scale(0.75);transform:scale(0.75)}.mfp-arrow-left{-webkit-transform-origin:0;transform-origin:0}.mfp-arrow-right{-webkit-transform-origin:100%;transform-origin:100%}.mfp-container{padding-left:6px;padding-right:6px}}.mfp-ie7 .mfp-img{padding:0}.mfp-ie7 .mfp-bottom-bar{width:600px;left:50%;margin-left:-300px;margin-top:5px;padding-bottom:5px}.mfp-ie7 .mfp-container{padding:0}.mfp-ie7 .mfp-content{padding-top:44px}.mfp-ie7 .mfp-close{top:0;right:0;padding-top:0}a:focus,button:focus{outline:0.2rem solid #C24E00;outline-offset:-2px;box-shadow:0 0 0 .3rem #f0f0f0}*{box-sizing:border-box}html{box-sizing:border-box;background-color:#FAFAFA;font-size:16px;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}@media (min-width: 48em){html{font-size:18px}}@media (min-width: 64em){html{font-size:20px}}@media (min-width: 80em){html{font-size:22px}}body{margin:0}::-moz-selection{color:#fff;background:#000}::selection{color:#fff;background:#000}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}a{color:#a3470a}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{max-width:100%;width:auto\9;height:auto;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}input[type="search"]{box-sizing:border-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}html{position:relative;min-height:100%}body{margin:0;padding:0;color:#252a34;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;line-height:1.5}body.overflow--hidden{overflow:hidden}h1,h2,h3,h4,h5,h6{margin:2em 0 0.5em;line-height:1.2;font-family:"Cartridge","Roboto","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-weight:bold}h1{margin-top:0;font-size:1.563em}h2{font-size:1.25em}h3{font-size:1em}h4{font-size:.75em}h5{font-size:.75em}h6{font-size:.75em}small,.small{font-size:.75em}p{margin-bottom:1.3em}u,ins{text-decoration:none;border-bottom:1px solid #252a34}u a,ins a{color:inherit}del a{color:inherit}p,pre,blockquote,ul,ol,dl,figure,table,fieldset{orphans:3;widows:3}abbr[title],abbr[data-original-title]{text-decoration:none;cursor:help;border-bottom:1px dotted #252a34}blockquote{margin:2em 1em 2em 0;padding-left:1em;padding-right:1em;font-style:italic;border-left:0.25em solid #C24E00}blockquote cite{font-style:italic}blockquote cite:before{content:"\2014";padding-right:5px}a:visited{color:#863c0b}a:hover{color:#b56c3b;outline:0}tt,code,kbd,samp,pre{font-family:Monaco,Consolas,"Lucida Console",monospace}pre{overflow-x:auto}p>code,a>code,li>code,figcaption>code,td>code{padding-top:0.1rem;padding-bottom:0.1rem;font-size:0.8em;background:#f8f8f8;border-radius:4px}p>code:before,p>code:after,a>code:before,a>code:after,li>code:before,li>code:after,figcaption>code:before,figcaption>code:after,td>code:before,td>code:after{letter-spacing:-0.2em;content:"\00a0"}hr{display:block;margin:1em 0;border:0;border-top:1px solid #cbcbcb}ul li,ol li{margin-bottom:0.5em}li ul,li ol{margin-top:0.5em}figure{display:-webkit-box;display:flex;-webkit-box-pack:justify;justify-content:space-between;-webkit-box-align:start;align-items:flex-start;flex-wrap:wrap;margin:2em 0}figure img,figure iframe,figure .fluid-width-video-wrapper{margin-bottom:1em}figure img{width:100%;border-radius:4px;-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}figure>a{display:block}@media (min-width: 37.5em){figure.half>a,figure.half>img{width:calc(50% - 0.5em)}}figure.half figcaption{width:100%}@media (min-width: 37.5em){figure.third>a,figure.third>img{width:calc(33.3333% - 0.5em)}}figure.third figcaption{width:100%}figcaption{margin-bottom:0.5em;color:#51555d;font-family:sans-serif;font-size:.75em}figcaption a{-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}figcaption a:hover{color:#b56c3b}svg:not(:root){overflow:hidden}nav ul{margin:0;padding:0}nav li{list-style:none}nav a{text-decoration:none}nav ul li,nav ol li{margin-bottom:0}nav li ul,nav li ol{margin-top:0}b,i,strong,em,blockquote,p,q,span,figure,img,h1,h2,header,input,a,tr,td,form button,input[type="submit"],.btn,#goog-wm-sb,.highlight,.archive__item-teaser{-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}form{margin:0 0 5px 0;padding:1em;background-color:#d7d7d7}form fieldset{margin-bottom:5px;padding:0;border-width:0}form legend{display:block;width:100%;margin-bottom:10px;*margin-left:-7px;padding:0;color:#252a34;border:0;white-space:normal}form p{margin-bottom:2.5px}form ul{list-style-type:none;margin:0 0 5px 0;padding:0}form br{display:none}label,input,button,select,textarea{vertical-align:baseline;*vertical-align:middle}input,button,select,textarea{box-sizing:border-box;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif}label{display:block;margin-bottom:0.25em;color:#252a34;cursor:pointer}label small{font-size:.75em}label input,label textarea,label select{display:block}input,textarea,select{display:inline-block;width:100%;padding:0.25em;margin-bottom:0.5em;color:#252a34;background-color:#FAFAFA;border:#cbcbcb;border-radius:4px;box-shadow:0 1px 1px rgba(0,0,0,0.125)}.input-mini{width:60px}.input-small{width:90px}input[type="image"],input[type="checkbox"],input[type="radio"]{width:auto;height:auto;padding:0;margin:3px 0;*margin-top:0;line-height:normal;cursor:pointer;border-radius:0;border:0 \9}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*width:13px;*height:13px}input[type="image"]{border:0;box-shadow:none}input[type="file"]{width:auto;padding:initial;line-height:initial;border:initial;background-color:transparent;background-color:initial;box-shadow:none}input[type="button"],input[type="reset"],input[type="submit"]{width:auto;height:auto;cursor:pointer;*overflow:visible}select,input[type="file"]{*margin-top:4px}select{width:auto;background-color:#fff}select[multiple],select[size]{height:auto}textarea{resize:vertical;height:auto;overflow:auto;vertical-align:top}input[type="hidden"]{display:none}.form{position:relative}.radio,.checkbox{padding-left:18px;font-weight:normal}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-18px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{opacity:0.5;cursor:not-allowed}input:focus,textarea:focus{border-color:#C24E00;outline:0;outline:thin dotted \9;box-shadow:inset 0 1px 3px rgba(37,42,52,0.06),0 0 5px rgba(194,78,0,0.7)}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus,select:focus{box-shadow:none}.help-block,.help-inline{color:#51555d}.help-block{display:block;margin-bottom:1em;line-height:1em}.help-inline{display:inline-block;vertical-align:middle;padding-left:5px}.form-group{margin-bottom:5px;padding:0;border-width:0}.form-inline input,.form-inline textarea,.form-inline select{display:inline-block;margin-bottom:0}.form-inline label{display:inline-block}.form-inline .radio,.form-inline .checkbox,.form-inline .radio{padding-left:0;margin-bottom:0;vertical-align:middle}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-left:0;margin-right:3px}.form-search input,.form-search textarea,.form-search select{display:inline-block;margin-bottom:0}.form-search .search-query{padding-left:14px;padding-right:14px;margin-bottom:0;border-radius:14px}.form-search label{display:inline-block}.form-search .radio,.form-search .checkbox,.form-inline .radio{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"]{float:left;margin-left:0;margin-right:3px}.form--loading:before{content:""}.form--loading .form__spinner{display:block}.form:before{position:absolute;top:0;left:0;width:100%;height:100%;background-color:rgba(255,255,255,0.7);z-index:10}.form__spinner{display:none;position:absolute;top:50%;left:50%;z-index:11}#goog-fixurl ul{list-style:none;margin-left:0;padding-left:0}#goog-fixurl ul li{list-style-type:none}#goog-wm-qt{width:auto;margin-right:10px;margin-bottom:20px;padding:8px 20px;display:inline-block;font-size:.75em;background-color:#fff;color:#000;border-width:2px !important;border-style:solid !important;border-color:#cbcbcb;border-radius:4px}table{display:block;margin-bottom:1em;width:100%;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em;border-collapse:collapse;overflow-x:auto}table+table{margin-top:1em}thead{background-color:#cbcbcb;border-bottom:2px solid #989898}th{padding:0.5em;font-weight:bold;text-align:left}td{padding:0.5em;border-bottom:1px solid #989898}tr,td,th{vertical-align:middle}@-webkit-keyframes intro{0%{opacity:0}100%{opacity:1}}@keyframes intro{0%{opacity:0}100%{opacity:1}}.btn,#goog-wm-sb{display:inline-block;margin-bottom:0.25em;padding:0.5em 1em;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em;font-weight:bold;text-align:center;text-decoration:none;border-width:0;border-radius:4px;cursor:pointer}.btn .icon,#goog-wm-sb .icon{margin-right:0.5em}.btn .icon+.hidden,#goog-wm-sb .icon+.hidden{margin-left:-0.5em}.btn--primary{background-color:#C24E00;color:#fff}.btn--primary:visited{background-color:#C24E00;color:#fff}.btn--primary:hover{background-color:#9b3e00;color:#fff}.btn--inverse{background-color:#fff;color:#3d4144;border:1px solid #cbcbcb}.btn--inverse:visited{background-color:#fff;color:#3d4144}.btn--inverse:hover{background-color:#ccc;color:#3d4144}.btn--light-outline{background-color:transparent;color:#fff;border:1px solid #fff}.btn--light-outline:visited{background-color:transparent;color:#fff}.btn--light-outline:hover{background-color:rgba(0,0,0,0.2);color:#fff}.btn--success{background-color:#3fa63f;color:#fff}.btn--success:visited{background-color:#3fa63f;color:#fff}.btn--success:hover{background-color:#328532;color:#fff}.btn--warning{background-color:#d67f05;color:#fff}.btn--warning:visited{background-color:#d67f05;color:#fff}.btn--warning:hover{background-color:#ab6604;color:#fff}.btn--danger{background-color:#ee5f5b;color:#fff}.btn--danger:visited{background-color:#ee5f5b;color:#fff}.btn--danger:hover{background-color:#be4c49;color:#fff}.btn--info{background-color:#3b9cba;color:#fff}.btn--info:visited{background-color:#3b9cba;color:#fff}.btn--info:hover{background-color:#2f7d95;color:#fff}.btn--facebook{background-color:#3b5998;color:#fff}.btn--facebook:visited{background-color:#3b5998;color:#fff}.btn--facebook:hover{background-color:#2f477a;color:#fff}.btn--twitter{background-color:#55acee;color:#fff}.btn--twitter:visited{background-color:#55acee;color:#fff}.btn--twitter:hover{background-color:#448abe;color:#fff}.btn--linkedin{background-color:#007bb6;color:#fff}.btn--linkedin:visited{background-color:#007bb6;color:#fff}.btn--linkedin:hover{background-color:#006292;color:#fff}.btn--block{display:block;width:100%}.btn--block+.btn--block{margin-top:0.25em}.btn--disabled{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);box-shadow:none;opacity:0.65}.btn--x-large{font-size:1.25em}.btn--large{font-size:1em}.btn--small{font-size:.6875em}.notice{margin:2em 0 !important;padding:1em;color:#252a34;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em !important;text-indent:initial;background-color:#eeefef;border-radius:4px;box-shadow:0 1px 1px rgba(189,193,196,0.25)}.notice h4{margin-top:0 !important;margin-bottom:0.75em;line-height:inherit}.page__content .notice h4{margin-bottom:0;font-size:1em}.notice p:last-child{margin-bottom:0 !important}.notice h4+p{margin-top:0;padding-top:0}.notice a{color:#aaaeb0}.notice a:hover{color:#5f6162}.notice code{background-color:#f4f4f5}.notice pre code{background-color:inherit}.notice ul:last-child{margin-bottom:0}.notice--primary{margin:2em 0 !important;padding:1em;color:#252a34;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em !important;text-indent:initial;background-color:#efd8c8;border-radius:4px;box-shadow:0 1px 1px rgba(194,78,0,0.25)}.notice--primary h4{margin-top:0 !important;margin-bottom:0.75em;line-height:inherit}.page__content .notice--primary h4{margin-bottom:0;font-size:1em}.notice--primary p:last-child{margin-bottom:0 !important}.notice--primary h4+p{margin-top:0;padding-top:0}.notice--primary a{color:#af4600}.notice--primary a:hover{color:#612700}.notice--primary code{background-color:#f4e9e1}.notice--primary pre code{background-color:inherit}.notice--primary ul:last-child{margin-bottom:0}.notice--info{margin:2em 0 !important;padding:1em;color:#252a34;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em !important;text-indent:initial;background-color:#d4e7ed;border-radius:4px;box-shadow:0 1px 1px rgba(59,156,186,0.25)}.notice--info h4{margin-top:0 !important;margin-bottom:0.75em;line-height:inherit}.page__content .notice--info h4{margin-bottom:0;font-size:1em}.notice--info p:last-child{margin-bottom:0 !important}.notice--info h4+p{margin-top:0;padding-top:0}.notice--info a{color:#358ca7}.notice--info a:hover{color:#1e4e5d}.notice--info code{background-color:#e7f1f4}.notice--info pre code{background-color:inherit}.notice--info ul:last-child{margin-bottom:0}.notice--warning{margin:2em 0 !important;padding:1em;color:#252a34;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em !important;text-indent:initial;background-color:#f3e1c9;border-radius:4px;box-shadow:0 1px 1px rgba(214,127,5,0.25)}.notice--warning h4{margin-top:0 !important;margin-bottom:0.75em;line-height:inherit}.page__content .notice--warning h4{margin-bottom:0;font-size:1em}.notice--warning p:last-child{margin-bottom:0 !important}.notice--warning h4+p{margin-top:0;padding-top:0}.notice--warning a{color:#c17205}.notice--warning a:hover{color:#6b4003}.notice--warning code{background-color:#f6eee2}.notice--warning pre code{background-color:inherit}.notice--warning ul:last-child{margin-bottom:0}.notice--success{margin:2em 0 !important;padding:1em;color:#252a34;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em !important;text-indent:initial;background-color:#d5e9d5;border-radius:4px;box-shadow:0 1px 1px rgba(63,166,63,0.25)}.notice--success h4{margin-top:0 !important;margin-bottom:0.75em;line-height:inherit}.page__content .notice--success h4{margin-bottom:0;font-size:1em}.notice--success p:last-child{margin-bottom:0 !important}.notice--success h4+p{margin-top:0;padding-top:0}.notice--success a{color:#399539}.notice--success a:hover{color:#205320}.notice--success code{background-color:#e7f2e7}.notice--success pre code{background-color:inherit}.notice--success ul:last-child{margin-bottom:0}.notice--danger{margin:2em 0 !important;padding:1em;color:#252a34;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em !important;text-indent:initial;background-color:#f8dbda;border-radius:4px;box-shadow:0 1px 1px rgba(238,95,91,0.25)}.notice--danger h4{margin-top:0 !important;margin-bottom:0.75em;line-height:inherit}.page__content .notice--danger h4{margin-bottom:0;font-size:1em}.notice--danger p:last-child{margin-bottom:0 !important}.notice--danger h4+p{margin-top:0;padding-top:0}.notice--danger a{color:#d65652}.notice--danger a:hover{color:#77302e}.notice--danger code{background-color:#f9ebea}.notice--danger pre code{background-color:inherit}.notice--danger ul:last-child{margin-bottom:0}.masthead{position:relative;border-bottom:1px solid #cbcbcb;-webkit-animation:intro 0.3s both;animation:intro 0.3s both;-webkit-animation-delay:0.15s;animation-delay:0.15s;z-index:20}.masthead__inner-wrap{clear:both;margin-left:auto;margin-right:auto;padding:1em;max-width:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif}.masthead__inner-wrap::after{clear:both;content:"";display:table}@media (min-width: 80em){.masthead__inner-wrap{max-width:1280px}}.masthead__inner-wrap nav{z-index:10}.masthead__inner-wrap a{text-decoration:none}.site-logo img{max-height:2rem}.site-title{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-item-align:center;align-self:center;font-weight:bold;z-index:20}.site-subtitle{display:block;font-size:.625em}.masthead__menu{float:left;margin-left:0;margin-right:0;width:100%;clear:both}.masthead__menu .site-nav{margin-left:0}@media (min-width: 37.5em){.masthead__menu .site-nav{float:right}}.masthead__menu ul{margin:0;padding:0;clear:both;list-style-type:none}.masthead__menu-item{display:block;list-style-type:none;white-space:nowrap}.masthead__menu-item--lg{padding-right:2em;font-weight:700}.breadcrumbs{clear:both;margin:0 auto;max-width:100%;padding-left:1em;padding-right:1em;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;-webkit-animation:intro 0.3s both;animation:intro 0.3s both;-webkit-animation-delay:0.3s;animation-delay:0.3s}.breadcrumbs::after{clear:both;content:"";display:table}@media (min-width: 80em){.breadcrumbs{max-width:1280px}}.breadcrumbs ol{padding:0;list-style:none;font-size:.75em}@media (min-width: 64em){.breadcrumbs ol{float:right;width:calc(100% - 200px)}}@media (min-width: 80em){.breadcrumbs ol{width:calc(100% - 300px)}}.breadcrumbs li{display:inline}.breadcrumbs .current{font-weight:bold}.pagination{clear:both;float:left;margin-top:1em;padding-top:1em;width:100%}.pagination::after{clear:both;content:"";display:table}.pagination ul{margin:0;padding:0;list-style-type:none;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif}.pagination li{display:block;float:left;margin-left:-1px}.pagination li a{display:block;margin-bottom:0.25em;padding:0.5em 1em;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:14px;font-weight:bold;line-height:1.5;text-align:center;text-decoration:none;color:#51555d;border:1px solid #989898;border-radius:0}.pagination li a:hover{color:#b56c3b}.pagination li a.current,.pagination li a.current.disabled{color:#FAFAFA;background:#C24E00}.pagination li a.disabled{color:rgba(81,85,93,0.5);pointer-events:none;cursor:not-allowed}.pagination li:first-child{margin-left:0}.pagination li:first-child a{border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination li:last-child a{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination--pager{display:block;padding:1em 2em;float:left;width:50%;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:1em;font-weight:bold;text-align:center;text-decoration:none;color:#51555d;border:1px solid #989898;border-radius:4px}.pagination--pager:hover{background-color:#51555d;color:#fff}.pagination--pager:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.pagination--pager:last-child{margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.pagination--pager.disabled{color:rgba(81,85,93,0.5);pointer-events:none;cursor:not-allowed}.page__content+.pagination,.page__meta+.pagination,.comment__date+.pagination,.page__share+.pagination,.page__comments+.pagination{margin-top:2em;padding-top:2em;border-top:1px solid #cbcbcb}.greedy-nav{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;min-height:2em;background:#FAFAFA}.greedy-nav a{display:block;margin:1rem;color:#007053;text-decoration:none}.greedy-nav a:hover{color:#005a42}.greedy-nav a.site-logo{margin-left:0;margin-right:0.5rem}.greedy-nav a.site-title{margin-left:0}.greedy-nav__toggle{-ms-flex-item-align:center;align-self:center;height:2rem;border:0;outline:none;background-color:transparent;cursor:pointer}.greedy-nav .visible-links{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;-webkit-box-flex:1;-ms-flex:1;flex:1;overflow:hidden}.greedy-nav .visible-links li{-webkit-box-flex:0;-ms-flex:none;flex:none}.greedy-nav .visible-links a{position:relative}.greedy-nav .visible-links a:before{content:"";position:absolute;left:0;bottom:0;height:4px;background:#C24E00;width:100%;-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out;-webkit-transform:scaleX(0) translate3d(0, 0, 0);transform:scaleX(0) translate3d(0, 0, 0)}.greedy-nav .visible-links a:hover:before{-webkit-transform:scaleX(1);-ms-transform:scaleX(1);transform:scaleX(1)}.greedy-nav .hidden-links{position:absolute;top:100%;right:0;margin-top:15px;padding:5px;border:1px solid #cbcbcb;border-radius:4px;background:#FAFAFA;-webkit-box-shadow:0 2px 4px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12);box-shadow:0 2px 4px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12)}.greedy-nav .hidden-links.hidden{display:none}.greedy-nav .hidden-links a{margin:0;padding:10px 20px;font-size:1em}.greedy-nav .hidden-links a:hover{color:#005a42;background:#b4b4b4}.greedy-nav .hidden-links:before{content:"";position:absolute;top:-11px;right:10px;width:0;border-style:solid;border-width:0 10px 10px;border-color:#cbcbcb transparent;display:block;z-index:0}.greedy-nav .hidden-links:after{content:"";position:absolute;top:-10px;right:10px;width:0;border-style:solid;border-width:0 10px 10px;border-color:#FAFAFA transparent;display:block;z-index:1}.greedy-nav .hidden-links li{display:block;border-bottom:1px solid #cbcbcb}.greedy-nav .hidden-links li:last-child{border-bottom:none}.no-js .greedy-nav .visible-links{-ms-flex-wrap:wrap;flex-wrap:wrap;overflow:visible}.nav__list{margin-bottom:1.5em}.nav__list input[type="checkbox"],.nav__list label{display:none}@media (max-width: 63.9375em){.nav__list label{position:relative;display:inline-block;padding:0.5em 2.5em 0.5em 1em;color:#7a8288;font-size:.75em;font-weight:bold;border:1px solid #bdc1c4;border-radius:4px;z-index:20;-webkit-transition:0.2s ease-out;transition:0.2s ease-out;cursor:pointer}.nav__list label:before,.nav__list label:after{content:"";position:absolute;right:1em;top:1.25em;width:0.75em;height:0.125em;line-height:1;background-color:#7a8288;-webkit-transition:0.2s ease-out;transition:0.2s ease-out}.nav__list label:after{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.nav__list label:hover{color:#fff;border-color:#7a8288;background-color:#333}.nav__list label:hover:before,.nav__list label:hover:after{background-color:#fff}.nav__list input:checked+label{color:white;background-color:#333}.nav__list input:checked+label:before,.nav__list input:checked+label:after{background-color:#fff}.nav__list label:hover:after{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.nav__list input:checked+label:hover:after{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}.nav__list ul{margin-bottom:1em}.nav__list a{display:block;padding:0.25em 0}}@media (max-width: 63.9375em) and (min-width: 64em){.nav__list a{padding-top:0.125em;padding-bottom:0.125em}}@media (max-width: 63.9375em){.nav__list a:hover{text-decoration:underline}}.nav__list .nav__items{margin:0;font-size:1.25rem}.nav__list .nav__items a{color:inherit}.nav__list .nav__items .active{margin-left:-0.5em;padding-left:0.5em;padding-right:0.5em;font-weight:bold}@media (max-width: 63.9375em){.nav__list .nav__items{position:relative;max-height:0;opacity:0%;overflow:hidden;z-index:10;-webkit-transition:0.3s ease-in-out;transition:0.3s ease-in-out;-webkit-transform:translate(0, 10%);-ms-transform:translate(0, 10%);transform:translate(0, 10%)}}@media (max-width: 63.9375em){.nav__list input:checked ~ .nav__items{-webkit-transition:0.5s ease-in-out;transition:0.5s ease-in-out;max-height:9999px;overflow:visible;opacity:1;margin-top:1em;-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);transform:translate(0, 0)}}.nav__title{margin:0;padding:0.5rem 0.75rem;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:1em;font-weight:bold}.nav__sub-title{display:block;margin:0.5rem 0;padding:0.25rem 0;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em;font-weight:bold;text-transform:uppercase;border-bottom:1px solid #cbcbcb}.toc{font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;color:#7a8288;background-color:#FAFAFA;border:1px solid #cbcbcb;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.125);box-shadow:0 1px 1px rgba(0,0,0,0.125)}.toc .nav__title{color:#fff;font-size:.75em;background:#C24E00;border-top-left-radius:4px;border-top-right-radius:4px}.toc .active a{box-shadow:0 0 0 0.1rem #c6906b}.toc__menu{margin:0;padding:0;width:100%;list-style:none;font-size:.75em}@media (min-width: 64em){.toc__menu{font-size:.6875em}}.toc__menu a{display:block;padding:0.25rem 0.75rem;color:#007053;font-weight:bold;line-height:1.5;border-bottom:1px solid #cbcbcb}.toc__menu a:hover{color:#252a34}.toc__menu li ul>li a{padding-left:1.25rem;font-weight:normal}.toc__menu li ul li ul>li a{padding-left:1.75rem}.toc__menu li ul li ul li ul>li a{padding-left:2.25rem}.toc__menu li ul li ul li ul li ul>li a{padding-left:2.75rem}.toc__menu li ul li ul li ul li ul li ul>li a{padding-left:3.25rem}.page__footer{clear:both;float:left;margin-left:0;margin-right:0;width:100%;clear:both;margin-top:3em;color:#51555d;-webkit-animation:intro 0.3s both;animation:intro 0.3s both;-webkit-animation-delay:0.45s;animation-delay:0.45s;background-color:#d5e5e1}.page__footer::after{clear:both;content:"";display:table}.page__footer footer{clear:both;margin-left:auto;margin-right:auto;margin-top:2em;max-width:100%;padding:0 1em 2em}.page__footer footer::after{clear:both;content:"";display:table}@media (min-width: 80em){.page__footer footer{max-width:1280px}}.page__footer a{color:inherit;text-decoration:none}.page__footer a:hover{text-decoration:underline}.page__footer .fas,.page__footer .fab,.page__footer .far,.page__footer .fal{color:#51555d}.page__footer-copyright{font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.6875em}.page__footer-follow ul{margin:0;padding:0;list-style-type:none}.page__footer-follow li{display:inline-block;padding-top:5px;padding-bottom:5px;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em;text-transform:uppercase}.page__footer-follow li+li:before{content:"";padding-right:5px}.page__footer-follow a{padding-right:10px;font-weight:bold}.page__footer-follow .social-icons a{white-space:nowrap}.layout--search .archive__item-teaser{margin-bottom:0.25em}.search__toggle{margin-left:1rem;margin-right:1rem;height:2rem;border:0;outline:none;color:#C24E00;background-color:transparent;cursor:pointer;-webkit-transition:0.2s;transition:0.2s}.search__toggle:hover{color:#923b00}.search-icon{width:100%;height:100%}.search-content{display:none;visibility:hidden;padding-top:1em;padding-bottom:1em}.search-content__inner-wrap{width:100%;margin-left:auto;margin-right:auto;padding-left:1em;padding-right:1em;-webkit-animation:intro 0.3s both;animation:intro 0.3s both;-webkit-animation-delay:0.15s;animation-delay:0.15s}@media (min-width: 80em){.search-content__inner-wrap{max-width:1280px}}.search-content__form{background-color:transparent}.search-content .search-input{display:block;margin-bottom:0;padding:0;border:none;outline:none;box-shadow:none;background-color:transparent;font-size:1.563em}@media (min-width: 64em){.search-content .search-input{font-size:1.953em}}@media (min-width: 80em){.search-content .search-input{font-size:2.441em}}.search-content.is--visible{display:block;visibility:visible}.search-content.is--visible::after{content:"";display:block}.search-content .results__found{margin-top:0.5em;font-size:.75em}.search-content .archive__item{margin-bottom:2em}@media (min-width: 64em){.search-content .archive__item{width:75%}}@media (min-width: 80em){.search-content .archive__item{width:50%}}.search-content .archive__item-title{margin-top:0}.search-content .archive__item-excerpt{margin-bottom:0}.ais-search-box{max-width:100% !important;margin-bottom:2em}.archive__item-title .ais-Highlight{color:#C24E00;font-style:normal;text-decoration:underline}.archive__item-excerpt .ais-Highlight{color:#C24E00;font-style:normal;font-weight:bold}div.highlighter-rouge,figure.highlight{position:relative;margin-bottom:1em;background:#263238;color:#eff;font-family:Monaco,Consolas,"Lucida Console",monospace;font-size:.75em;line-height:1.8;border-radius:4px}div.highlighter-rouge>pre,div.highlighter-rouge pre.highlight,figure.highlight>pre,figure.highlight pre.highlight{margin:0;padding:1em}.highlight table{margin-bottom:0;font-size:1em;border:0}.highlight table td{padding:0;width:calc(100% - 1em);border:0}.highlight table td.gutter,.highlight table td.rouge-gutter{padding-right:1em;width:1em;color:#b2ccd6;border-right:1px solid #b2ccd6;text-align:right}.highlight table td.code,.highlight table td.rouge-code{padding-left:1em}.highlight table pre{margin:0}.highlight pre{width:100%}.highlight .hll{background-color:#eff}.highlight .c{color:#b2ccd6}.highlight .err{color:#f07178}.highlight .k{color:#c792ea}.highlight .l{color:#f78c6c}.highlight .n{color:#eff}.highlight .o{color:#89ddff}.highlight .p{color:#eff}.highlight .cm{color:#b2ccd6}.highlight .cp{color:#b2ccd6}.highlight .c1{color:#b2ccd6}.highlight .cs{color:#b2ccd6}.highlight .gd{color:#f07178}.highlight .ge{font-style:italic}.highlight .gh{color:#eff;font-weight:bold}.highlight .gi{color:#c3e88d}.highlight .gp{color:#b2ccd6;font-weight:bold}.highlight .gs{font-weight:bold}.highlight .gu{color:#89ddff;font-weight:bold}.highlight .kc{color:#c792ea}.highlight .kd{color:#c792ea}.highlight .kn{color:#89ddff}.highlight .kp{color:#c792ea}.highlight .kr{color:#c792ea}.highlight .kt{color:#ffcb6b}.highlight .ld{color:#c3e88d}.highlight .m{color:#f78c6c}.highlight .s{color:#c3e88d}.highlight .na{color:#82aaff}.highlight .nb{color:#eff}.highlight .nc{color:#ffcb6b}.highlight .no{color:#f07178}.highlight .nd{color:#89ddff}.highlight .ni{color:#eff}.highlight .ne{color:#f07178}.highlight .nf{color:#82aaff}.highlight .nl{color:#eff}.highlight .nn{color:#ffcb6b}.highlight .nx{color:#82aaff}.highlight .py{color:#eff}.highlight .nt{color:#89ddff}.highlight .nv{color:#f07178}.highlight .ow{color:#89ddff}.highlight .w{color:#eff}.highlight .mf{color:#f78c6c}.highlight .mh{color:#f78c6c}.highlight .mi{color:#f78c6c}.highlight .mo{color:#f78c6c}.highlight .sb{color:#c3e88d}.highlight .sc{color:#eff}.highlight .sd{color:#b2ccd6}.highlight .s2{color:#c3e88d}.highlight .se{color:#f78c6c}.highlight .sh{color:#c3e88d}.highlight .si{color:#f78c6c}.highlight .sx{color:#c3e88d}.highlight .sr{color:#c3e88d}.highlight .s1{color:#c3e88d}.highlight .ss{color:#c3e88d}.highlight .bp{color:#eff}.highlight .vc{color:#f07178}.highlight .vg{color:#f07178}.highlight .vi{color:#f07178}.highlight .il{color:#f78c6c}.gist th,.gist td{border-bottom:0}.hidden,.is--hidden{display:none;visibility:hidden}.load{display:none}.transparent{opacity:0}.visually-hidden,.screen-reader-text,.screen-reader-text span,.screen-reader-shortcut{position:absolute !important;clip:rect(1px, 1px, 1px, 1px);height:1px !important;width:1px !important;border:0 !important;overflow:hidden}body:hover .visually-hidden a,body:hover .visually-hidden input,body:hover .visually-hidden button{display:none !important}.screen-reader-text:focus,.screen-reader-shortcut:focus{clip:auto !important;height:auto !important;width:auto !important;display:block;font-size:1em;font-weight:bold;padding:15px 23px 14px;background:#fff;z-index:100000;text-decoration:none;box-shadow:0 0 2px 2px rgba(0,0,0,0.6)}.skip-link{position:fixed;z-index:20;margin:0;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;white-space:nowrap}.skip-link li{height:0;width:0;list-style:none}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.task-list{padding:0}.task-list li{list-style-type:none}.task-list .task-list-item-checkbox{margin-right:0.5em;opacity:1}.task-list .task-list{margin-left:1em}.cf{clear:both}.wrapper{margin-left:auto;margin-right:auto;width:100%}.align-left{display:block;margin-left:auto;margin-right:auto}@media (min-width: 37.5em){.align-left{float:left;margin-right:1em}}.align-right{display:block;margin-left:auto;margin-right:auto}@media (min-width: 37.5em){.align-right{float:right;margin-left:1em}}.align-center{display:block;margin-left:auto;margin-right:auto}@media (min-width: 64em){.full{margin-right:-20.3389830508% !important}}.icon{display:inline-block;fill:currentColor;width:1em;height:1.1em;line-height:1;position:relative;top:-0.1em;vertical-align:middle}.social-icons .fas,.social-icons .fab,.social-icons .far,.social-icons .fal{color:#252a34}.social-icons .fa-behance,.social-icons .fa-behance-square{color:#1769ff}.social-icons .fa-bitbucket{color:#205081}.social-icons .fa-dribbble,.social-icons .fa-dribble-square{color:#ea4c89}.social-icons .fa-facebook,.social-icons .fa-facebook-square,.social-icons .fa-facebook-f{color:#3b5998}.social-icons .fa-flickr{color:#ff0084}.social-icons .fa-foursquare{color:#0072b1}.social-icons .fa-github,.social-icons .fa-github-alt,.social-icons .fa-github-square{color:inherit}.social-icons .fa-gitlab{color:#e24329}.social-icons .fa-instagram{color:#517fa4}.social-icons .fa-keybase{color:#ef7639}.social-icons .fa-lastfm,.social-icons .fa-lastfm-square{color:#d51007}.social-icons .fa-linkedin,.social-icons .fa-linkedin-in{color:#007bb6}.social-icons .fa-mastodon,.social-icons .fa-mastodon-square{color:#2b90d9}.social-icons .fa-pinterest,.social-icons .fa-pinterest-p,.social-icons .fa-pinterest-square{color:#cb2027}.social-icons .fa-reddit{color:#ff4500}.social-icons .fa-rss,.social-icons .fa-rss-square{color:#fa9b39}.social-icons .fa-soundcloud{color:#f30}.social-icons .fa-stack-exchange,.social-icons .fa-stack-overflow{color:#fe7a15}.social-icons .fa-tumblr,.social-icons .fa-tumblr-square{color:#32506d}.social-icons .fa-twitter,.social-icons .fa-twitter-square{color:#55acee}.social-icons .fa-vimeo,.social-icons .fa-vimeo-square,.social-icons .fa-vimeo-v{color:#1ab7ea}.social-icons .fa-vine{color:#00bf8f}.social-icons .fa-youtube{color:#b00}.social-icons .fa-xing,.social-icons .fa-xing-square{color:#006567}.navicon{position:relative;width:1.5rem;height:.25rem;background:#C24E00;margin:auto;-webkit-transition:0.3s;transition:0.3s}.navicon:before,.navicon:after{content:"";position:absolute;left:0;width:1.5rem;height:.25rem;background:#C24E00;-webkit-transition:0.3s;transition:0.3s}.navicon:before{top:-.5rem}.navicon:after{bottom:-.5rem}.close .navicon{background:transparent}.close .navicon:before,.close .navicon:after{-webkit-transform-origin:50% 50%;-ms-transform-origin:50% 50%;transform-origin:50% 50%;top:0;width:1.5rem}.close .navicon:before{-webkit-transform:rotate3d(0, 0, 1, 45deg);transform:rotate3d(0, 0, 1, 45deg)}.close .navicon:after{-webkit-transform:rotate3d(0, 0, 1, -45deg);transform:rotate3d(0, 0, 1, -45deg)}.greedy-nav__toggle:hover .navicon,.greedy-nav__toggle:hover .navicon:before,.greedy-nav__toggle:hover .navicon:after{background:#923b00}.greedy-nav__toggle:hover.close .navicon{background:transparent}@media (min-width: 64em){.sticky{clear:both;position:-webkit-sticky;position:sticky;top:2em}.sticky::after{clear:both;content:"";display:table}.sticky>*{display:block}}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.show-modal{overflow:hidden;position:relative}.show-modal:before{position:absolute;content:"";top:0;left:0;width:100%;height:100%;z-index:999;background-color:rgba(255,255,255,0.85)}.show-modal .modal{display:block}.modal{display:none;position:fixed;width:300px;top:50%;left:50%;margin-left:-150px;margin-top:-150px;min-height:0;z-index:9999;background:#fff;border:1px solid #cbcbcb;border-radius:4px;box-shadow:0 1px 1px rgba(0,0,0,0.125)}.modal__title{margin:0;padding:0.5em 1em}.modal__supporting-text{padding:0 1em 0.5em 1em}.modal__actions{padding:0.5em 1em;border-top:1px solid #cbcbcb}.footnote{color:#9ba1a6;text-decoration:none}.footnotes{color:#9ba1a6}.footnotes ol,.footnotes li,.footnotes p{margin-bottom:0;font-size:.75em}a.reversefootnote{color:#7a8288;text-decoration:none}a.reversefootnote:hover{text-decoration:underline}.required{color:#ee5f5b;font-weight:bold}.gsc-control-cse table,.gsc-control-cse tr,.gsc-control-cse td{border:0}.responsive-video-container{position:relative;margin-bottom:1em;padding-bottom:56.25%;height:0;overflow:hidden;max-width:100%}.responsive-video-container iframe,.responsive-video-container object,.responsive-video-container embed{position:absolute;top:0;left:0;width:100%;height:100%}:-webkit-full-screen-ancestor .masthead,:-webkit-full-screen-ancestor .page__footer{position:static}#main{clear:both;margin-left:auto;margin-right:auto;padding-left:1em;padding-right:1em;-webkit-animation:intro 0.3s both;animation:intro 0.3s both;max-width:100%;-webkit-animation-delay:0.15s;animation-delay:0.15s}#main::after{clear:both;content:"";display:table}@media (min-width: 80em){#main{max-width:1280px}}body{display:-webkit-box;display:-ms-flexbox;display:flex;min-height:100vh;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.initial-content,.search-content{flex:1 0 auto}@media (min-width: 64em){.page{float:right;width:calc(100% - 200px);padding-right:200px}}@media (min-width: 80em){.page{width:calc(100% - 300px);padding-right:300px}}.page .page__inner-wrap{float:left;margin-top:1em;margin-left:0;margin-right:0;width:100%;clear:both}.page .page__inner-wrap .page__content,.page .page__inner-wrap .page__meta,.page .page__inner-wrap .comment__date,.page .page__inner-wrap .page__share{position:relative;float:left;margin-left:0;margin-right:0;width:100%;clear:both}.page__title{margin-top:0;line-height:1}.page__title+.page__meta,.page__title+.comment__date{margin-top:-0.5em}.page__lead{font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:1.25em}.page__content h1 .header-link,.page__content h2 .header-link,.page__content h3 .header-link,.page__content h4 .header-link,.page__content h5 .header-link,.page__content h6 .header-link{position:relative;left:0.5em;opacity:0;font-size:0.8em;-webkit-transition:opacity 0.2s ease-in-out 0.1s;-moz-transition:opacity 0.2s ease-in-out 0.1s;-o-transition:opacity 0.2s ease-in-out 0.1s;transition:opacity 0.2s ease-in-out 0.1s}.page__content h1:hover .header-link,.page__content h2:hover .header-link,.page__content h3:hover .header-link,.page__content h4:hover .header-link,.page__content h5:hover .header-link,.page__content h6:hover .header-link{opacity:1}.page__content p,.page__content li,.page__content dl{font-size:1em}.page__content p{margin:0 0 1.3em}.page__content a:not(.btn):not(#goog-wm-sb):hover{text-decoration:underline}.page__content a:not(.btn):not(#goog-wm-sb):hover img{box-shadow:0 0 10px rgba(0,0,0,0.25)}.page__content dt{margin-top:1em;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-weight:bold}.page__content dd{margin-left:1em;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em}.page__content .small{font-size:.75em}.page__content blockquote+.small{margin-top:-1.5em;padding-left:1.25rem}.page__hero{position:relative;margin-bottom:2em;clear:both;-webkit-animation:intro 0.3s both;animation:intro 0.3s both;-webkit-animation-delay:0.25s;animation-delay:0.25s}.page__hero::after{clear:both;content:"";display:table}.page__hero--overlay{position:relative;margin-bottom:2em;padding:3em 0;clear:both;background-size:cover;background-repeat:no-repeat;background-position:center;-webkit-animation:intro 0.3s both;animation:intro 0.3s both;-webkit-animation-delay:0.25s;animation-delay:0.25s}.page__hero--overlay::after{clear:both;content:"";display:table}.page__hero--overlay a{color:#fff}.page__hero--overlay .wrapper{padding-left:1em;padding-right:1em}@media (min-width: 80em){.page__hero--overlay .wrapper{max-width:1280px}}.page__hero--overlay .page__title,.page__hero--overlay .page__meta,.page__hero--overlay .comment__date,.page__hero--overlay .page__lead{color:#fff;text-shadow:1px 1px 4px rgba(0,0,0,0.5)}.page__hero--overlay .btn,.page__hero--overlay #goog-wm-sb{color:#FAFAFA}.page__hero--overlay .page__lead{max-width:768px}.page__hero--overlay .page__title{font-size:1.953em}@media (min-width: 37.5em){.page__hero--overlay .page__title{font-size:2.441em}}.page__hero-image{width:100%;height:auto;-ms-interpolation-mode:bicubic}.page__hero-caption{position:absolute;bottom:0;right:0;margin:0 auto;padding:2px 5px;color:#fff;font-family:sans-serif;font-size:.6875em;background:#000;text-align:right;z-index:5;opacity:0.5;border-radius:4px 0 0 0}@media (min-width: 64em){.page__hero-caption{padding:5px 10px}}.page__hero-caption a{color:#fff;text-decoration:none}.page__share{margin-top:2em;padding-top:1em;border-top:1px solid #cbcbcb}@media (max-width: 37.5em){.page__share .btn span,.page__share #goog-wm-sb span{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}}.page__share-title{margin-bottom:10px;font-size:.75em;text-transform:uppercase}.page__meta,.comment__date{margin-top:2em;color:#51555d;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em}.page__meta p,.comment__date p{margin:0}.page__meta a,.comment__date a{color:inherit}.page__meta-title{margin-bottom:10px;font-size:.75em;text-transform:uppercase}.page__taxonomy .sep{display:none}.page__taxonomy strong{margin-right:10px}.page__taxonomy-item{display:inline-block;margin-right:5px;margin-bottom:8px;padding:5px 10px;text-decoration:none;border:1px solid #989898;border-radius:4px}.page__taxonomy-item:hover{text-decoration:none;color:#b56c3b}.taxonomy__section{margin-bottom:2em;padding-bottom:1em}.taxonomy__section:not(:last-child){border-bottom:solid 1px #cbcbcb}.taxonomy__section .archive__item-title{margin-top:0}.taxonomy__section .archive__subtitle{clear:both;border:0}.taxonomy__section+.taxonomy__section{margin-top:2em}.taxonomy__title{margin-bottom:0.5em;color:#3a4252}.taxonomy__count{color:#3a4252}.taxonomy__index{display:grid;grid-column-gap:2em;grid-template-columns:repeat(2, 1fr);margin:1.414em 0;padding:0;font-size:0.75em;list-style:none}@media (min-width: 64em){.taxonomy__index{grid-template-columns:repeat(3, 1fr)}}.taxonomy__index a{display:-webkit-box;display:-ms-flexbox;display:flex;padding:0.25em 0;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;color:inherit;text-decoration:none;border-bottom:1px solid #cbcbcb}.back-to-top{display:block;clear:both;color:#9ea7ba;font-size:0.6em;text-transform:uppercase;text-align:right;text-decoration:none}.page__comments{float:left;margin-left:0;margin-right:0;width:100%;clear:both}.page__comments-title{margin-top:2rem;margin-bottom:10px;padding-top:2rem;font-size:.75em;border-top:1px solid #cbcbcb;text-transform:uppercase}.page__comments-form{-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.page__comments-form.disabled input,.page__comments-form.disabled button,.page__comments-form.disabled textarea,.page__comments-form.disabled label{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);box-shadow:none;opacity:0.65}.comment{clear:both;margin:1em 0}.comment::after{clear:both;content:"";display:table}.comment:not(:last-child){border-bottom:1px solid #cbcbcb}.comment__avatar-wrapper{float:left;width:60px;height:60px}@media (min-width: 64em){.comment__avatar-wrapper{width:100px;height:100px}}.comment__avatar{width:40px;height:40px;border-radius:50%}@media (min-width: 64em){.comment__avatar{width:80px;height:80px;padding:5px;border:1px solid #cbcbcb}}.comment__content-wrapper{float:right;width:calc(100% - 60px)}@media (min-width: 64em){.comment__content-wrapper{width:calc(100% - 100px)}}.comment__author{margin:0}.comment__author a{text-decoration:none}.comment__date{margin:0}.comment__date a{text-decoration:none}.page__related{clear:both;float:left;margin-top:2em;padding-top:1em;border-top:1px solid #cbcbcb}.page__related::after{clear:both;content:"";display:table}@media (min-width: 64em){.page__related{float:right;width:calc(100% - 200px)}}@media (min-width: 80em){.page__related{width:calc(100% - 300px)}}.page__related a{color:inherit;text-decoration:none}.page__related-title{margin-bottom:10px;font-size:.75em;text-transform:uppercase}@media (min-width: 64em){.wide .page{padding-right:0}}@media (min-width: 80em){.wide .page{padding-right:0}}@media (min-width: 64em){.wide .page__related{padding-right:0}}@media (min-width: 80em){.wide .page__related{padding-right:0}}.archive{margin-top:1em;margin-bottom:2em}@media (min-width: 64em){.archive{float:right;width:calc(100% - 200px);padding-right:200px}}@media (min-width: 80em){.archive{width:calc(100% - 300px);padding-right:300px}}.archive__item{position:relative}.archive__item a{position:relative;z-index:10}.archive__item a[rel="permalink"]{position:static}.archive__subtitle{margin:1.414em 0 0;padding-bottom:0.5em;font-size:1em;color:#51555d;border-bottom:1px solid #cbcbcb}.archive__subtitle+.list__item .archive__item-title{margin-top:0.5em}.archive__item-title{margin-bottom:0.25em;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;line-height:initial;overflow:hidden;text-overflow:ellipsis}.archive__item-title a[rel="permalink"]::before{content:'';position:absolute;left:0;top:0;right:0;bottom:0}.archive__item-title a+a{opacity:0.5}.page__content .archive__item-title{margin-top:1em;border-bottom:none}.archive__item-excerpt{margin-top:0;font-size:.75em}.archive__item-excerpt+p{text-indent:0}.archive__item-excerpt a{position:relative}.archive__item-teaser{position:relative;border-radius:4px;overflow:hidden}.archive__item-teaser img{width:100%}.archive__item-caption{position:absolute;bottom:0;right:0;margin:0 auto;padding:2px 5px;color:#fff;font-family:sans-serif;font-size:.625em;background:#000;text-align:right;z-index:5;opacity:0.5;border-radius:4px 0 0 0}@media (min-width: 64em){.archive__item-caption{padding:5px 10px}}.archive__item-caption a{color:#fff;text-decoration:none}.list__item .page__meta,.list__item .comment__date{margin:0 0 4px;font-size:0.6em}@media (min-width: 64em){.archive .grid__wrapper{margin-right:-200px}}@media (min-width: 80em){.archive .grid__wrapper{margin-right:-300px}}.grid__item{margin-bottom:2em}@media (min-width: 37.5em){.grid__item{float:left;width:48.9795918367%}.grid__item:nth-child(2n+1){clear:both;margin-left:0}.grid__item:nth-child(2n+2){clear:none;margin-left:2.0408163265%}}@media (min-width: 48em){.grid__item{margin-left:0;margin-right:0;width:23.7288135593%}.grid__item:nth-child(2n+1){clear:none}.grid__item:nth-child(4n+1){clear:both}.grid__item:nth-child(4n+2){clear:none;margin-left:1.6949152542%}.grid__item:nth-child(4n+3){clear:none;margin-left:1.6949152542%}.grid__item:nth-child(4n+4){clear:none;margin-left:1.6949152542%}}.grid__item .page__meta,.grid__item .comment__date{margin:0 0 4px;font-size:0.6em}.grid__item .archive__item-title{margin-top:0.5em;font-size:1em}.grid__item .archive__item-excerpt{display:none}@media (min-width: 48em){.grid__item .archive__item-excerpt{display:block;font-size:.75em}}@media (min-width: 37.5em){.grid__item .archive__item-teaser{max-height:200px}}@media (min-width: 48em){.grid__item .archive__item-teaser{max-height:120px}}.feature__wrapper{clear:both;margin-bottom:2em;border-bottom:1px solid #cbcbcb}.feature__wrapper::after{clear:both;content:"";display:table}.feature__wrapper .archive__item-title{margin-bottom:0}.feature__item{position:relative;margin-bottom:2em;font-size:1.125em}@media (min-width: 37.5em){.feature__item{float:left;margin-bottom:0;width:32.2033898305%}.feature__item:nth-child(3n+1){clear:both;margin-left:0}.feature__item:nth-child(3n+2){clear:none;margin-left:1.6949152542%}.feature__item:nth-child(3n+3){clear:none;margin-left:1.6949152542%}.feature__item .feature__item-teaser{max-height:200px;overflow:hidden}}.feature__item .archive__item-body{padding-left:1.6949152542%;padding-right:1.6949152542%}.feature__item a.btn::before,.feature__item a#goog-wm-sb::before{content:'';position:absolute;left:0;top:0;right:0;bottom:0}.feature__item--left{position:relative;float:left;margin-left:0;margin-right:0;width:100%;clear:both;font-size:1.125em}.feature__item--left .archive__item{float:left}.feature__item--left .archive__item-teaser{margin-bottom:2em}.feature__item--left a.btn::before,.feature__item--left a#goog-wm-sb::before{content:'';position:absolute;left:0;top:0;right:0;bottom:0}@media (min-width: 37.5em){.feature__item--left .archive__item-teaser{float:left;width:40.6779661017%}.feature__item--left .archive__item-body{float:right;padding-left:1.6949152542%;padding-right:1.6949152542%;width:57.6271186441%}}.feature__item--right{position:relative;float:left;margin-left:0;margin-right:0;width:100%;clear:both;font-size:1.125em}.feature__item--right .archive__item{float:left}.feature__item--right .archive__item-teaser{margin-bottom:2em}.feature__item--right a.btn::before,.feature__item--right a#goog-wm-sb::before{content:'';position:absolute;left:0;top:0;right:0;bottom:0}@media (min-width: 37.5em){.feature__item--right{text-align:right}.feature__item--right .archive__item-teaser{float:right;width:40.6779661017%}.feature__item--right .archive__item-body{float:left;width:57.6271186441%;padding-left:1.6949152542%;padding-right:1.6949152542%}}.feature__item--center{position:relative;float:left;margin-left:0;margin-right:0;width:100%;clear:both;font-size:1.125em}.feature__item--center .archive__item{float:left;width:100%}.feature__item--center .archive__item-teaser{margin-bottom:2em}.feature__item--center a.btn::before,.feature__item--center a#goog-wm-sb::before{content:'';position:absolute;left:0;top:0;right:0;bottom:0}@media (min-width: 37.5em){.feature__item--center{text-align:center}.feature__item--center .archive__item-teaser{margin:0 auto;width:40.6779661017%}.feature__item--center .archive__item-body{margin:0 auto;width:57.6271186441%}}.archive .feature__wrapper .archive__item-title{margin-top:0.25em;font-size:1em}.archive .feature__item,.archive .feature__item--left,.archive .feature__item--center,.archive .feature__item--right{font-size:1em}@media (min-width: 64em){.wide .archive{padding-right:0}}@media (min-width: 80em){.wide .archive{padding-right:0}}.layout--single .feature__wrapper{display:inline-block}.sidebar{clear:both}.sidebar::after{clear:both;content:"";display:table}@media (min-width: 64em){.sidebar{float:left;width:calc(200px - 1em);opacity:0.75;-webkit-transition:opacity 0.2s ease-in-out;transition:opacity 0.2s ease-in-out}.sidebar:hover{opacity:1}.sidebar.sticky{overflow-y:auto;max-height:calc(100vh - 2em - 2em)}}@media (min-width: 80em){.sidebar{width:calc(300px - 1em)}}.sidebar>*{margin-top:1em;margin-bottom:1em}.sidebar h2,.sidebar h3,.sidebar h4,.sidebar h5,.sidebar h6{margin-bottom:0;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif}.sidebar p,.sidebar li{font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:.75em;line-height:1.5}.sidebar img{width:100%}.sidebar img.emoji{width:20px;height:20px}.sidebar__right{margin-bottom:1em}@media (min-width: 64em){.sidebar__right{position:absolute;top:0;right:0;width:200px;margin-right:-200px;padding-left:1em;z-index:10}.sidebar__right.sticky{clear:both;position:-webkit-sticky;position:sticky;top:2em;float:right}.sidebar__right.sticky::after{clear:both;content:"";display:table}}@media (min-width: 80em){.sidebar__right{width:300px;margin-right:-300px}}@media (min-width: 64em){.splash .sidebar__right{position:relative;float:right;margin-right:0}}@media (min-width: 80em){.splash .sidebar__right{margin-right:0}}.author__avatar{display:table-cell;vertical-align:top;width:36px;height:36px}@media (min-width: 64em){.author__avatar{display:block;width:auto;height:auto}}.author__avatar img{max-width:110px;border-radius:50%}@media (min-width: 64em){.author__avatar img{padding:5px;border:1px solid #cbcbcb}}.author__content{display:table-cell;vertical-align:top;padding-left:15px;padding-right:25px;line-height:1}@media (min-width: 64em){.author__content{display:block;width:100%;padding-left:0;padding-right:0}}.author__content a{color:inherit;text-decoration:none}.author__name{margin:0}@media (min-width: 64em){.author__name{margin-top:10px;margin-bottom:10px}}.sidebar .author__name{font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;font-size:1em}.author__bio{margin:0}@media (min-width: 64em){.author__bio{margin-top:10px;margin-bottom:20px}}.author__urls-wrapper{position:relative;display:table-cell;vertical-align:middle;font-family:"Atkinson-Hyperlegible",-apple-system,BlinkMacSystemFont,"Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Arial,sans-serif;z-index:20;cursor:pointer}.author__urls-wrapper li:last-child a{margin-bottom:0}.author__urls-wrapper .author__urls span.label{padding-left:5px}@media (min-width: 64em){.author__urls-wrapper{display:block}}.author__urls-wrapper button{position:relative;margin-bottom:0}@supports (pointer-events: none){.author__urls-wrapper button:before{content:'';position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none}}.author__urls-wrapper button.open:before{pointer-events:auto}@media (min-width: 64em){.author__urls-wrapper button{display:none}}.author__urls{display:none;position:absolute;right:0;margin-top:15px;padding:10px;list-style-type:none;border:1px solid #cbcbcb;border-radius:4px;background:#FAFAFA;box-shadow:0 2px 4px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12);cursor:default}.author__urls.is--visible{display:block}@media (min-width: 64em){.author__urls{display:block;position:relative;margin:0;padding:0;border:0;background:transparent;box-shadow:none}}.author__urls:before{display:block;content:"";position:absolute;top:-11px;left:calc(50% - 10px);width:0;border-style:solid;border-width:0 10px 10px;border-color:#cbcbcb transparent;z-index:0}@media (min-width: 64em){.author__urls:before{display:none}}.author__urls:after{display:block;content:"";position:absolute;top:-10px;left:calc(50% - 10px);width:0;border-style:solid;border-width:0 10px 10px;border-color:#FAFAFA transparent;z-index:1}@media (min-width: 64em){.author__urls:after{display:none}}.author__urls ul{padding:10px;list-style-type:none}.author__urls li{white-space:nowrap}.author__urls a{display:block;margin-bottom:5px;padding-right:5px;padding-top:2px;padding-bottom:2px;color:inherit;font-size:1em;text-decoration:none}.author__urls a:hover{text-decoration:underline}.wide .sidebar__right{margin-bottom:1em}@media (min-width: 64em){.wide .sidebar__right{position:initial;top:initial;right:initial;width:initial;margin-right:initial;padding-left:initial;z-index:initial}.wide .sidebar__right.sticky{float:none}}@media (min-width: 80em){.wide .sidebar__right{width:initial;margin-right:initial}}@media print{[hidden]{display:none}*{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}html{margin:0;padding:0;min-height:auto !important;font-size:16px}body{margin:0 auto;background:#fff !important;color:#000 !important;font-size:1rem;line-height:1.5;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}h1,h2,h3,h4,h5,h6{color:#000;line-height:1.2;margin-bottom:0.75rem;margin-top:0}h1{font-size:2.5rem}h2{font-size:2rem}h3{font-size:1.75rem}h4{font-size:1.5rem}h5{font-size:1.25rem}h6{font-size:1rem}a,a:visited{color:#000;text-decoration:underline;word-wrap:break-word}table{border-collapse:collapse}thead{display:table-header-group}table,th,td{border-bottom:1px solid #000}td,th{padding:8px 16px}img{border:0;display:block;max-width:100% !important;vertical-align:middle}hr{border:0;border-bottom:2px solid #bbb;height:0;margin:2.25rem 0;padding:0}dt{font-weight:bold}dd{margin:0;margin-bottom:0.75rem}abbr[title],acronym[title]{border:0;text-decoration:none}table,blockquote,pre,code,figure,li,hr,ul,ol,a,tr{page-break-inside:avoid}h2,h3,h4,p,a{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid;page-break-inside:avoid}h1+p,h2+p,h3+p{page-break-before:avoid}img{page-break-after:auto;page-break-before:auto;page-break-inside:avoid}pre{white-space:pre-wrap !important;word-wrap:break-word}a[href^='http://']:after,a[href^='https://']:after,a[href^='ftp://']:after{content:" (" attr(href) ")";font-size:80%}abbr[title]:after,acronym[title]:after{content:" (" attr(title) ")"}#main{max-width:100%}.page{margin:0;padding:0;width:100%}.page-break,.page-break-before{page-break-before:always}.page-break-after{page-break-after:always}.no-print{display:none}a.no-reformat:after{content:''}abbr[title].no-reformat:after,acronym[title].no-reformat:after{content:''}.page__hero-caption{color:#000 !important;background:#fff !important;opacity:1}.page__hero-caption a{color:#000 !important}.masthead,.toc,.page__share,.page__related,.pagination,.ads,.page__footer,.page__comments-form,.author__avatar,.author__content,.author__urls-wrapper,.nav__list,.sidebar,.adsbygoogle{display:none !important;height:1px !important}}.pagination li a.disabled{color:rgba(241,241,241,0.8)}.sidebar{opacity:1}.footnote{color:#252a34;text-decoration:none}.footnotes{color:#252a34}.notice a{color:#a3470a}.notice a:visited{color:#863c0b}.notice a:hover{color:#b56c3b}.page__content h1 .header-link:focus,.page__content h2 .header-link:focus,.page__content h3 .header-link:focus,.page__content h4 .header-link:focus,.page__content h5 .header-link:focus,.page__content h6 .header-link:focus{opacity:unset}a:focus,button:focus,.bigfoot-footnote__button:focus,summary:focus{outline:.2rem solid #f0f0f0;box-shadow:0 0 0 .3rem #007053} diff --git a/assets/fonts/Cartridge-Bold.woff2 b/assets/fonts/Cartridge-Bold.woff2 new file mode 100644 index 000000000..62ccbd9c9 Binary files /dev/null and b/assets/fonts/Cartridge-Bold.woff2 differ diff --git a/assets/fonts/Cartridge-Regular.woff2 b/assets/fonts/Cartridge-Regular.woff2 new file mode 100644 index 000000000..07b998c3b Binary files /dev/null and b/assets/fonts/Cartridge-Regular.woff2 differ diff --git a/assets/fonts/academicons.eot b/assets/fonts/academicons.eot new file mode 100755 index 000000000..aeac7091e Binary files /dev/null and b/assets/fonts/academicons.eot differ diff --git a/assets/fonts/academicons.svg b/assets/fonts/academicons.svg new file mode 100755 index 000000000..2599b714b --- /dev/null +++ b/assets/fonts/academicons.svg @@ -0,0 +1,107 @@ + + + + + + +{ + "fontFamily": "Academicons", + "majorVersion": 1, + "minorVersion": 8, + "fontURL": "https://jpswalsh.github.io/academicons/", + "description": "Font generated by IcoMoon.", + "designer": "James Walsh and Katja Bercic", + "designerURL": "http://jpswalsh.com", + "license": "SIL OFL 1.1", + "licenseURL": "http://scripts.sil.org/OFL", + "version": "Version 1.8", + "fontId": "Academicons", + "psName": "Academicons", + "subFamily": "Regular", + "fullName": "Academicons" +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/fonts/academicons.ttf b/assets/fonts/academicons.ttf new file mode 100755 index 000000000..4f42f958c Binary files /dev/null and b/assets/fonts/academicons.ttf differ diff --git a/assets/fonts/academicons.woff b/assets/fonts/academicons.woff new file mode 100755 index 000000000..11bb0c8ca Binary files /dev/null and b/assets/fonts/academicons.woff differ diff --git a/assets/fonts/atkinson-hyperlegible-bold-102a.woff2 b/assets/fonts/atkinson-hyperlegible-bold-102a.woff2 new file mode 100644 index 000000000..19a58eace Binary files /dev/null and b/assets/fonts/atkinson-hyperlegible-bold-102a.woff2 differ diff --git a/assets/fonts/atkinson-hyperlegible-regular-102a.woff2 b/assets/fonts/atkinson-hyperlegible-regular-102a.woff2 new file mode 100644 index 000000000..99b3c6f5e Binary files /dev/null and b/assets/fonts/atkinson-hyperlegible-regular-102a.woff2 differ diff --git a/assets/images/ExampleTodoList.png b/assets/images/ExampleTodoList.png new file mode 100644 index 000000000..59a759acd Binary files /dev/null and b/assets/images/ExampleTodoList.png differ diff --git a/assets/images/OAC_Banner.png b/assets/images/OAC_Banner.png new file mode 100644 index 000000000..fb2658349 Binary files /dev/null and b/assets/images/OAC_Banner.png differ diff --git a/assets/images/OAC_Landing.png b/assets/images/OAC_Landing.png new file mode 100644 index 000000000..9df656c4b Binary files /dev/null and b/assets/images/OAC_Landing.png differ diff --git a/assets/images/Online_Archive_of_California_-_Browse_Map.png b/assets/images/Online_Archive_of_California_-_Browse_Map.png new file mode 100644 index 000000000..5921e94a2 Binary files /dev/null and b/assets/images/Online_Archive_of_California_-_Browse_Map.png differ diff --git a/assets/images/ThinkingToolAlphaboxNotes.pdf b/assets/images/ThinkingToolAlphaboxNotes.pdf new file mode 100644 index 000000000..e032ca9d2 Binary files /dev/null and b/assets/images/ThinkingToolAlphaboxNotes.pdf differ diff --git a/assets/images/ThinkingToolTopicTermsMap.docx b/assets/images/ThinkingToolTopicTermsMap.docx new file mode 100644 index 000000000..1fed63dad Binary files /dev/null and b/assets/images/ThinkingToolTopicTermsMap.docx differ diff --git a/assets/images/Zoolander_Files_in_Computer.gif b/assets/images/Zoolander_Files_in_Computer.gif new file mode 100644 index 000000000..8bc3fd87a Binary files /dev/null and b/assets/images/Zoolander_Files_in_Computer.gif differ diff --git a/assets/images/apple-touch-icon-114x114-precomposed.png b/assets/images/apple-touch-icon-114x114-precomposed.png new file mode 100644 index 000000000..edae9d92e Binary files /dev/null and b/assets/images/apple-touch-icon-114x114-precomposed.png differ diff --git a/assets/images/apple-touch-icon-144x144-precomposed.png b/assets/images/apple-touch-icon-144x144-precomposed.png new file mode 100644 index 000000000..b8c42534a Binary files /dev/null and b/assets/images/apple-touch-icon-144x144-precomposed.png differ diff --git a/assets/images/apple-touch-icon-72x72-precomposed.png b/assets/images/apple-touch-icon-72x72-precomposed.png new file mode 100644 index 000000000..0bb841603 Binary files /dev/null and b/assets/images/apple-touch-icon-72x72-precomposed.png differ diff --git a/assets/images/apple-touch-icon-precomposed.png b/assets/images/apple-touch-icon-precomposed.png new file mode 100644 index 000000000..96d7666f8 Binary files /dev/null and b/assets/images/apple-touch-icon-precomposed.png differ diff --git a/assets/images/b-t-dust-in-the-wind.gif b/assets/images/b-t-dust-in-the-wind.gif new file mode 100644 index 000000000..141ea0c56 Binary files /dev/null and b/assets/images/b-t-dust-in-the-wind.gif differ diff --git a/assets/images/bio-photo.jpg b/assets/images/bio-photo.jpg new file mode 100644 index 000000000..b0aefa8a3 Binary files /dev/null and b/assets/images/bio-photo.jpg differ diff --git a/assets/images/bloomington-city-directories.jpg b/assets/images/bloomington-city-directories.jpg new file mode 100644 index 000000000..5870d91a8 Binary files /dev/null and b/assets/images/bloomington-city-directories.jpg differ diff --git a/assets/images/coverpfpo.jpg b/assets/images/coverpfpo.jpg new file mode 100644 index 000000000..0999547a6 Binary files /dev/null and b/assets/images/coverpfpo.jpg differ diff --git a/assets/images/critlib-not-sure.jpg b/assets/images/critlib-not-sure.jpg new file mode 100644 index 000000000..82bae047f Binary files /dev/null and b/assets/images/critlib-not-sure.jpg differ diff --git a/assets/images/critlib-petagogy.jpg b/assets/images/critlib-petagogy.jpg new file mode 100644 index 000000000..bf82f614e Binary files /dev/null and b/assets/images/critlib-petagogy.jpg differ diff --git a/assets/images/db-ab-95.png b/assets/images/db-ab-95.png new file mode 100644 index 000000000..08cae838f Binary files /dev/null and b/assets/images/db-ab-95.png differ diff --git a/assets/images/db-ab-o.png b/assets/images/db-ab-o.png new file mode 100644 index 000000000..d4254b776 Binary files /dev/null and b/assets/images/db-ab-o.png differ diff --git a/assets/images/db-ab.png b/assets/images/db-ab.png new file mode 100644 index 000000000..4efcf228c Binary files /dev/null and b/assets/images/db-ab.png differ diff --git a/assets/images/default-thumb.png b/assets/images/default-thumb.png new file mode 100644 index 000000000..8c61eacfa Binary files /dev/null and b/assets/images/default-thumb.png differ diff --git a/assets/images/doc-brown-testing.png b/assets/images/doc-brown-testing.png new file mode 100644 index 000000000..8e5588218 Binary files /dev/null and b/assets/images/doc-brown-testing.png differ diff --git a/assets/images/favicon.ico b/assets/images/favicon.ico new file mode 100755 index 000000000..06f05592c Binary files /dev/null and b/assets/images/favicon.ico differ diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100755 index 000000000..5f8b0b5c7 Binary files /dev/null and b/assets/images/favicon.png differ diff --git a/assets/images/indiana-historic-maps-screenshot.jpg b/assets/images/indiana-historic-maps-screenshot.jpg new file mode 100644 index 000000000..42a82b297 Binary files /dev/null and b/assets/images/indiana-historic-maps-screenshot.jpg differ diff --git a/assets/images/kathleen-fitzpatrick-announcement.png b/assets/images/kathleen-fitzpatrick-announcement.png new file mode 100644 index 000000000..99c3ecbc4 Binary files /dev/null and b/assets/images/kathleen-fitzpatrick-announcement.png differ diff --git a/assets/images/laluttecontinue-crop.jpg b/assets/images/laluttecontinue-crop.jpg new file mode 100644 index 000000000..1b0531483 Binary files /dev/null and b/assets/images/laluttecontinue-crop.jpg differ diff --git a/assets/images/laluttecontinue-thumb.jpg b/assets/images/laluttecontinue-thumb.jpg new file mode 100644 index 000000000..4d6cf653e Binary files /dev/null and b/assets/images/laluttecontinue-thumb.jpg differ diff --git a/assets/images/laluttecontinue-thumb1.jpg b/assets/images/laluttecontinue-thumb1.jpg new file mode 100644 index 000000000..c0680bc55 Binary files /dev/null and b/assets/images/laluttecontinue-thumb1.jpg differ diff --git a/assets/images/lb-tdgb.png b/assets/images/lb-tdgb.png new file mode 100644 index 000000000..cc99dcc99 Binary files /dev/null and b/assets/images/lb-tdgb.png differ diff --git a/assets/images/lg-gb.png b/assets/images/lg-gb.png new file mode 100644 index 000000000..8558f1e1b Binary files /dev/null and b/assets/images/lg-gb.png differ diff --git a/assets/images/lg-tb.png b/assets/images/lg-tb.png new file mode 100644 index 000000000..4da389d01 Binary files /dev/null and b/assets/images/lg-tb.png differ diff --git a/assets/images/lpLogoButton.jpg b/assets/images/lpLogoButton.jpg new file mode 100644 index 000000000..253e97617 Binary files /dev/null and b/assets/images/lpLogoButton.jpg differ diff --git a/assets/images/nicholas-basbanes-paper-talk.png b/assets/images/nicholas-basbanes-paper-talk.png new file mode 100644 index 000000000..1ee2a1099 Binary files /dev/null and b/assets/images/nicholas-basbanes-paper-talk.png differ diff --git a/assets/images/obsidian-tasks-clever-example.png b/assets/images/obsidian-tasks-clever-example.png new file mode 100644 index 000000000..8b52fda46 Binary files /dev/null and b/assets/images/obsidian-tasks-clever-example.png differ diff --git a/assets/images/patronus-cropped.jpg b/assets/images/patronus-cropped.jpg new file mode 100644 index 000000000..6732e46d1 Binary files /dev/null and b/assets/images/patronus-cropped.jpg differ diff --git a/assets/images/placeholder-square-1.jpg b/assets/images/placeholder-square-1.jpg new file mode 100644 index 000000000..ee3dcc1a9 Binary files /dev/null and b/assets/images/placeholder-square-1.jpg differ diff --git a/assets/images/pocket-notebooks-small.jpg b/assets/images/pocket-notebooks-small.jpg new file mode 100755 index 000000000..ff0cddc39 Binary files /dev/null and b/assets/images/pocket-notebooks-small.jpg differ diff --git a/assets/images/pocket-notebooks-square.jpg b/assets/images/pocket-notebooks-square.jpg new file mode 100644 index 000000000..6c976f41e Binary files /dev/null and b/assets/images/pocket-notebooks-square.jpg differ diff --git a/assets/images/pocket-notebooks.jpg b/assets/images/pocket-notebooks.jpg new file mode 100755 index 000000000..00f7b9832 Binary files /dev/null and b/assets/images/pocket-notebooks.jpg differ diff --git a/assets/images/potato-tron.gif b/assets/images/potato-tron.gif new file mode 100644 index 000000000..ca49d4ea2 Binary files /dev/null and b/assets/images/potato-tron.gif differ diff --git a/assets/images/raincross-underground.jpg b/assets/images/raincross-underground.jpg new file mode 100644 index 000000000..a5ca0e703 Binary files /dev/null and b/assets/images/raincross-underground.jpg differ diff --git a/assets/images/squiggle-default.png b/assets/images/squiggle-default.png new file mode 100644 index 000000000..a57784bf6 Binary files /dev/null and b/assets/images/squiggle-default.png differ diff --git a/assets/images/squiggle-hint.png b/assets/images/squiggle-hint.png new file mode 100644 index 000000000..cfee1837c Binary files /dev/null and b/assets/images/squiggle-hint.png differ diff --git a/assets/images/squiggle-preferred.png b/assets/images/squiggle-preferred.png new file mode 100644 index 000000000..d3afb54dd Binary files /dev/null and b/assets/images/squiggle-preferred.png differ diff --git a/assets/images/weekly-assemblage-thumb.png b/assets/images/weekly-assemblage-thumb.png new file mode 100644 index 000000000..95b2ae368 Binary files /dev/null and b/assets/images/weekly-assemblage-thumb.png differ diff --git a/assets/images/weekly-assemblage.png b/assets/images/weekly-assemblage.png new file mode 100644 index 000000000..562409845 Binary files /dev/null and b/assets/images/weekly-assemblage.png differ diff --git a/assets/js/_main.js b/assets/js/_main.js new file mode 100644 index 000000000..0efc97026 --- /dev/null +++ b/assets/js/_main.js @@ -0,0 +1,136 @@ +/* ========================================================================== + jQuery plugin settings and other scripts + ========================================================================== */ + +$(document).ready(function() { + // FitVids init + $("#main").fitVids(); + + // Sticky sidebar + var stickySideBar = function() { + var show = + $(".author__urls-wrapper button").length === 0 + ? $(window).width() > 1024 // width should match $large Sass variable + : !$(".author__urls-wrapper button").is(":visible"); + if (show) { + // fix + $(".sidebar").addClass("sticky"); + } else { + // unfix + $(".sidebar").removeClass("sticky"); + } + }; + + stickySideBar(); + + $(window).resize(function() { + stickySideBar(); + }); + + // Follow menu drop down + $(".author__urls-wrapper button").on("click", function() { + $(".author__urls").toggleClass("is--visible"); + $(".author__urls-wrapper button").toggleClass("open"); + }); + + // Close search screen with Esc key + $(document).keyup(function(e) { + if (e.keyCode === 27) { + if ($(".initial-content").hasClass("is--hidden")) { + $(".search-content").toggleClass("is--visible"); + $(".initial-content").toggleClass("is--hidden"); + } + } + }); + + // Search toggle + $(".search__toggle").on("click", function() { + $(".search-content").toggleClass("is--visible"); + $(".initial-content").toggleClass("is--hidden"); + // set focus on input + setTimeout(function() { + $(".search-content input").focus(); + }, 400); + }); + + // Smooth scrolling + var scroll = new SmoothScroll('a[href*="#"]', { + offset: 20, + speed: 400, + speedAsDuration: true, + durationMax: 500 + }); + + // Gumshoe scroll spy init + if($("nav.toc").length > 0) { + var spy = new Gumshoe("nav.toc a", { + // Active classes + navClass: "active", // applied to the nav list item + contentClass: "active", // applied to the content + + // Nested navigation + nested: false, // if true, add classes to parents of active link + nestedClass: "active", // applied to the parent items + + // Offset & reflow + offset: 20, // how far from the top of the page to activate a content area + reflow: true, // if true, listen for reflows + + // Event support + events: true // if true, emit custom events + }); + } + + // add lightbox class to all image links + $( + "a[href$='.jpg'],a[href$='.jpeg'],a[href$='.JPG'],a[href$='.png'],a[href$='.gif'],a[href$='.webp']" + ).addClass("image-popup"); + + // Magnific-Popup options + $(".image-popup").magnificPopup({ + // disableOn: function() { + // if( $(window).width() < 500 ) { + // return false; + // } + // return true; + // }, + type: "image", + tLoading: "Loading image #%curr%...", + gallery: { + enabled: true, + navigateByImgClick: true, + preload: [0, 1] // Will preload 0 - before current, and 1 after the current image + }, + image: { + tError: 'Image #%curr% could not be loaded.' + }, + removalDelay: 500, // Delay in milliseconds before popup is removed + // Class that is added to body when popup is open. + // make it unique to apply your CSS animations just to this exact popup + mainClass: "mfp-zoom-in", + callbacks: { + beforeOpen: function() { + // just a hack that adds mfp-anim class to markup + this.st.image.markup = this.st.image.markup.replace( + "mfp-figure", + "mfp-figure mfp-with-anim" + ); + } + }, + closeOnContentClick: true, + midClick: true // allow opening popup on middle mouse click. Always set it to true if you don't provide alternative source. + }); + + // Add anchors for headings + $('.page__content').find('h1, h2, h3, h4, h5, h6').each(function() { + var id = $(this).attr('id'); + if (id) { + var anchor = document.createElement("a"); + anchor.className = 'header-link'; + anchor.href = '#' + id; + anchor.innerHTML = 'Permalink'; + anchor.title = "Permalink"; + $(this).append(anchor); + } + }); +}); diff --git a/assets/js/bbigfoot.min.js b/assets/js/bbigfoot.min.js new file mode 100644 index 000000000..35d201cea --- /dev/null +++ b/assets/js/bbigfoot.min.js @@ -0,0 +1,39 @@ +(function(){(function($){return $.bigfoot=function(options){var addBreakpoint,baseFontSize,bigfoot,buttonHover,calculatePixelDimension,cleanFootnoteLinks,clickButton,createPopover,defaults,deleteEmptyOrHR,escapeKeypress,footnoteInit,getSetting,makeDefaultCallbacks,popoverStates,positionTooltip,removeBackLinks,removeBreakpoint,removePopovers,replaceWithReferenceAttributes,repositionFeet,roomCalc,settings,touchClick,unhoverFeet,updateSetting,viewportDetails;bigfoot=void 0;defaults={actionOriginalFN:"hide",activateCallback:function(){},activateOnHover:!1,allowMultipleFN:!1,anchorPattern:/(fn|footnote|note)[:\-_\d]/gi,anchorParentTagname:'sup',breakpoints:{},deleteOnUnhover:!1,footnoteParentClass:'footnote',footnoteTagname:'li',hoverDelay:250,numberResetSelector:void 0,popoverDeleteDelay:300,popoverCreateDelay:100,positionContent:!0,preventPageScroll:!0,scope:!1,useFootnoteOnlyOnce:!0,contentMarkup:"",buttonMarkup:"
"};settings=$.extend(defaults,options);popoverStates={};footnoteInit=function(){var $curResetElement,$currentLastFootnoteLink,$footnoteAnchors,$footnoteButton,$lastResetElement,$parent,$relevantFNLink,$relevantFootnote,finalFNLinks,footnoteButton,footnoteButtonSearchQuery,footnoteContent,footnoteIDNum,footnoteLinks,footnoteNum,footnotes,i,_i,_ref,_results;footnoteButtonSearchQuery=settings.scope?""+settings.scope+" a[href*='#']":"a[href*='#']";$footnoteAnchors=$(footnoteButtonSearchQuery).filter(function(){var $this,relAttr;$this=$(this);relAttr=$this.attr("rel");if(relAttr==="null"||(relAttr==null)){relAttr=""} +return(""+($this.attr("href"))+relAttr).match(settings.anchorPattern)&&$this.closest("[class*="+settings.footnoteParentClass+"]:not(a):not("+settings.anchorParentTagname+")").length<1});footnotes=[];footnoteLinks=[];finalFNLinks=[];cleanFootnoteLinks($footnoteAnchors,footnoteLinks);$(footnoteLinks).each(function(){var $closestFootnoteEl,relatedFN;relatedFN=$(this).data("footnote-ref").replace(/[:.+~*\]\[]/g,"\\$&");if(settings.useFootnoteOnlyOnce){relatedFN=""+relatedFN+":not(.footnote-processed)"} +$closestFootnoteEl=$(relatedFN).closest(settings.footnoteTagname);if($closestFootnoteEl.length>0){footnotes.push($closestFootnoteEl.first().addClass("footnote-processed"));return finalFNLinks.push(this)}});$currentLastFootnoteLink=$("[data-footnote-identifier]:last");footnoteIDNum=$currentLastFootnoteLink.length<1?0:+$currentLastFootnoteLink.data("footnote-identifier");_results=[];for(i=_i=0,_ref=footnotes.length;0<=_ref?_i<_ref:_i>_ref;i=0<=_ref?++_i:--_i){footnoteContent=removeBackLinks($(footnotes[i]).html().trim(),$(finalFNLinks[i]).data("footnote-backlink-ref"));footnoteContent=footnoteContent.replace(/"/g,""").replace(/</g,"<sym;").replace(/>/g,">sym;").replace(/'/g,"'");footnoteIDNum+=1;footnoteButton="";$relevantFNLink=$(finalFNLinks[i]);$relevantFootnote=$(footnotes[i]);if(settings.numberResetSelector!=null){$curResetElement=$relevantFNLink.closest(settings.numberResetSelector);if($curResetElement.is($lastResetElement)){footnoteNum+=1}else{footnoteNum=1} +$lastResetElement=$curResetElement}else{footnoteNum=footnoteIDNum} +if(footnoteContent.indexOf("<")!==0){footnoteContent="

"+footnoteContent+"

"} +footnoteButton=settings.buttonMarkup.replace(/\{\{FOOTNOTENUM\}\}/g,footnoteNum).replace(/\{\{FOOTNOTEID\}\}/g,footnoteIDNum).replace(/\{\{FOOTNOTECONTENT\}\}/g,footnoteContent);footnoteButton=replaceWithReferenceAttributes(footnoteButton,"SUP",$relevantFNLink);footnoteButton=replaceWithReferenceAttributes(footnoteButton,"FN",$relevantFootnote);$footnoteButton=$(footnoteButton).insertBefore($relevantFNLink);$parent=$relevantFootnote.parent();switch(settings.actionOriginalFN.toLowerCase()){case "hide":$relevantFNLink.addClass("footnote-print-only");$relevantFootnote.addClass("footnote-print-only");_results.push(deleteEmptyOrHR($parent));break;case "delete":$relevantFNLink.remove();$relevantFootnote.remove();_results.push(deleteEmptyOrHR($parent));break;default:_results.push($relevantFNLink.addClass("footnote-print-only"))}} +return _results};cleanFootnoteLinks=function($footnoteAnchors,footnoteLinks){var $parent,$supChild,linkHREF,linkID;if(footnoteLinks==null){footnoteLinks=[]} +$parent=void 0;$supChild=void 0;linkHREF=void 0;linkID=void 0;$footnoteAnchors.each(function(){var $child,$this;$this=$(this);linkHREF="#"+($this.attr("href")).split("#")[1];$parent=$this.closest(settings.anchorParentTagname);$child=$this.find(settings.anchorParentTagname);if($parent.length>0){linkID=($parent.attr("id")||"")+($this.attr("id")||"");return footnoteLinks.push($parent.attr({"data-footnote-backlink-ref":linkID,"data-footnote-ref":linkHREF}))}else if($child.length>0){linkID=($child.attr("id")||"")+($this.attr("id")||"");return footnoteLinks.push($this.attr({"data-footnote-backlink-ref":linkID,"data-footnote-ref":linkHREF}))}else{linkID=$this.attr("id")||"";return footnoteLinks.push($this.attr({"data-footnote-backlink-ref":linkID,"data-footnote-ref":linkHREF}))}})};deleteEmptyOrHR=function($el){var $parent;$parent=void 0;if($el.is(":empty")||$el.children(":not(.footnote-print-only)").length===0){$parent=$el.parent();if(settings.actionOriginalFN.toLowerCase()==="delete"){$el.remove()}else{$el.addClass("footnote-print-only")} +return deleteEmptyOrHR($parent)}else if($el.children(":not(.footnote-print-only)").length===$el.children("hr:not(.footnote-print-only)").length){$parent=$el.parent();if(settings.actionOriginalFN.toLowerCase()==="delete"){$el.remove()}else{$el.children("hr").addClass("footnote-print-only");$el.addClass("footnote-print-only")} +return deleteEmptyOrHR($parent)}};removeBackLinks=function(footnoteHTML,backlinkID){var regex;if(backlinkID.indexOf(' ')>=0){backlinkID=backlinkID.trim().replace(/\s+/g,"|").replace(/(.*)/g,"($1)")} +regex=new RegExp("(\\s| )*<\\s*a[^#<]*#"+backlinkID+"[^>]*>(.*?)<\\s*/\\s*a>","g");return footnoteHTML.replace(regex,"").replace("[]","")};replaceWithReferenceAttributes=function(string,referenceKeyword,$referenceElement){var refMatches,refRegex,refReplaceRegex,refReplaceText;refRegex=new RegExp("\\{\\{"+referenceKeyword+":([^\\}]*)\\}\\}","g");refMatches=void 0;refReplaceText=void 0;refReplaceRegex=void 0;refMatches=refRegex.exec(string);while(refMatches){if(refMatches[1]){refReplaceText=$referenceElement.attr(refMatches[1])||"";string=string.replace("{{"+referenceKeyword+":"+refMatches[1]+"}}",refReplaceText)} +refMatches=refRegex.exec(string)} +return string};buttonHover=function(event){var $buttonHovered,dataIdentifier,otherPopoverSelector;if(settings.activateOnHover){$buttonHovered=$(event.target).closest(".bigfoot-footnote__button");dataIdentifier="[data-footnote-identifier='"+($buttonHovered.attr("data-footnote-identifier"))+"']";if($buttonHovered.hasClass("is-active")){return} +$buttonHovered.addClass("is-hover-instantiated");if(!settings.allowMultipleFN){otherPopoverSelector=".bigfoot-footnote:not("+dataIdentifier+")";removePopovers(otherPopoverSelector)} +createPopover(".bigfoot-footnote__button"+dataIdentifier).addClass("is-hover-instantiated")}};touchClick=function(event){var $nearButton,$nearFootnote,$target;$target=$(event.target);$nearButton=$target.closest(".bigfoot-footnote__button");$nearFootnote=$target.closest(".bigfoot-footnote");if($nearButton.length>0){event.preventDefault();clickButton($nearButton)}else if($nearFootnote.length<1){if($(".bigfoot-footnote").length>0){removePopovers()}}};clickButton=function($button){var dataIdentifier;$button.blur();dataIdentifier="data-footnote-identifier='"+($button.attr("data-footnote-identifier"))+"'";if($button.hasClass("changing")){return}else if(!$button.hasClass("is-active")){$button.addClass("changing");setTimeout((function(){return $button.removeClass("changing")}),settings.popoverCreateDelay);createPopover(".bigfoot-footnote__button["+dataIdentifier+"]");$button.addClass("is-click-instantiated");if(!settings.allowMultipleFN){removePopovers(".bigfoot-footnote:not(["+dataIdentifier+"])")}}else{if(!settings.allowMultipleFN){removePopovers()}else{removePopovers(".bigfoot-footnote["+dataIdentifier+"]")}}};createPopover=function(selector){var $buttons,$popoversCreated;$buttons=void 0;if(typeof selector!=="string"&&settings.allowMultipleFN){$buttons=selector}else if(typeof selector!=="string"){$buttons=selector.first()}else if(settings.allowMultipleFN){$buttons=$(selector).closest(".bigfoot-footnote__button")}else{$buttons=$(selector+":first").closest(".bigfoot-footnote__button")} +$popoversCreated=$();$buttons.each(function(){var $content,$contentContainer,$this,content;$this=$(this);content=void 0;try{content=settings.contentMarkup.replace(/\{\{FOOTNOTENUM\}\}/g,$this.attr("data-footnote-number")).replace(/\{\{FOOTNOTEID\}\}/g,$this.attr("data-footnote-identifier")).replace(/\{\{FOOTNOTECONTENT\}\}/g,$this.attr("data-bigfoot-footnote")).replace(/\>sym\;/g,">").replace(/\<sym\;/g,"<");return content=replaceWithReferenceAttributes(content,"BUTTON",$this)}finally{$content=$(content);try{settings.activateCallback($content,$this)}catch(_error){} +$content.insertAfter($buttons);popoverStates[$this.attr("data-footnote-identifier")]="init";$content.attr("bigfoot-max-width",calculatePixelDimension($content.css("max-width"),$content));$content.css("max-width",10000);$contentContainer=$content.find(".bigfoot-footnote__content");$content.attr("data-bigfoot-max-height",calculatePixelDimension($contentContainer.css("max-height"),$contentContainer));repositionFeet();$this.addClass("is-active");$content.find(".bigfoot-footnote__content").bindScrollHandler();$popoversCreated=$popoversCreated.add($content)}});setTimeout((function(){return $popoversCreated.addClass("is-active")}),settings.popoverCreateDelay);return $popoversCreated};baseFontSize=function(){var el,size;el=document.createElement("div");el.style.cssText="display:inline-block;padding:0;line-height:1;position:absolute;visibility:hidden;font-size:1em;";el.appendChild(document.createElement("M"));document.body.appendChild(el);size=el.offsetHeight;document.body.removeChild(el);return size};calculatePixelDimension=function(dim,$el){if(dim==="none"){dim=10000}else if(dim.indexOf("rem")>=0){dim=parseFloat(dim)*baseFontSize()}else if(dim.indexOf("em")>=0){dim=parseFloat(dim)*parseFloat($el.css("font-size"))}else if(dim.indexOf("px")>=0){dim=parseFloat(dim);if(dim<=60){dim=dim/parseFloat($el.parent().css("width"))}}else if(dim.indexOf("%")>=0){dim=parseFloat(dim)/100} +return dim};$.fn.bindScrollHandler=function(){if(!settings.preventPageScroll){return $(this)} +$(this).on("DOMMouseScroll mousewheel",function(event){var $popover,$this,delta,height,prevent,scrollHeight,scrollTop,up;$this=$(this);scrollTop=$this.scrollTop();scrollHeight=$this[0].scrollHeight;height=parseInt($this.css("height"));$popover=$this.closest(".bigfoot-footnote");if($this.scrollTop()>0&&$this.scrollTop()<10){$popover.addClass("is-scrollable")} +if(!$popover.hasClass("is-scrollable")){return} +delta=event.type==="DOMMouseScroll"?event.originalEvent.detail*-40:event.originalEvent.wheelDelta;up=delta>0;prevent=function(){event.stopPropagation();event.preventDefault();event.returnValue=!1;return!1};if(!up&&-delta>scrollHeight-height-scrollTop){$this.scrollTop(scrollHeight);$popover.addClass("is-fully-scrolled");return prevent()}else if(up&&delta>scrollTop){$this.scrollTop(0);$popover.removeClass("is-fully-scrolled");return prevent()}else{return $popover.removeClass("is-fully-scrolled")}});return $(this)};unhoverFeet=function(e){if(settings.deleteOnUnhover&&settings.activateOnHover){return setTimeout((function(){var $target;$target=$(e.target).closest(".bigfoot-footnote, .bigfoot-footnote__button");if($(".bigfoot-footnote__button:hover, .bigfoot-footnote:hover").length<1){return removePopovers()}}),settings.hoverDelay)}};escapeKeypress=function(event){if(event.keyCode===27){return removePopovers()}};removePopovers=function(footnotes,timeout){var $buttonsClosed,$linkedButton,$this,footnoteID;if(footnotes==null){footnotes=".bigfoot-footnote"} +if(timeout==null){timeout=settings.popoverDeleteDelay} +$buttonsClosed=$();footnoteID=void 0;$linkedButton=void 0;$this=void 0;$(footnotes).each(function(){$this=$(this);footnoteID=$this.attr("data-footnote-identifier");$linkedButton=$(".bigfoot-footnote__button[data-footnote-identifier='"+footnoteID+"']");if(!$linkedButton.hasClass("changing")){$buttonsClosed=$buttonsClosed.add($linkedButton);$linkedButton.removeClass("is-active is-hover-instantiated is-click-instantiated").addClass("changing");$this.removeClass("is-active").addClass("disapearing");return setTimeout((function(){$this.remove();delete popoverStates[footnoteID];return $linkedButton.removeClass("changing")}),timeout)}});return $buttonsClosed};repositionFeet=function(e){var type;if(settings.positionContent){type=e?e.type:"resize";$(".bigfoot-footnote").each(function(){var $button,$contentWrapper,$mainWrap,$this,dataIdentifier,identifier,lastState,marginSize,maxHeightInCSS,maxHeightOnScreen,maxWidth,maxWidthInCSS,positionOnTop,relativeToWidth,roomLeft,totalHeight;$this=$(this);identifier=$this.attr("data-footnote-identifier");dataIdentifier="data-footnote-identifier='"+identifier+"'";$contentWrapper=$this.find(".bigfoot-footnote__content");$button=$this.siblings(".bigfoot-footnote__button");roomLeft=roomCalc($button);marginSize=parseFloat($this.css("margin-top"));maxHeightInCSS=+($this.attr("data-bigfoot-max-height"));totalHeight=2*marginSize+$this.outerHeight();maxHeightOnScreen=10000;positionOnTop=roomLeft.bottomRoomroomLeft.bottomRoom;lastState=popoverStates[identifier];if(positionOnTop){if(lastState!=="top"){popoverStates[identifier]="top";$this.addClass("is-positioned-top").removeClass("is-positioned-bottom");$this.css("transform-origin",(roomLeft.leftRelative*100)+"% 100%")} +maxHeightOnScreen=roomLeft.topRoom-marginSize-15}else{if(lastState!=="bottom"||lastState==="init"){popoverStates[identifier]="bottom";$this.removeClass("is-positioned-top").addClass("is-positioned-bottom");$this.css("transform-origin",(roomLeft.leftRelative*100)+"% 0%")} +maxHeightOnScreen=roomLeft.bottomRoom-marginSize-15} +$this.find(".bigfoot-footnote__content").css({"max-height":Math.min(maxHeightOnScreen,maxHeightInCSS)+"px"});if(type==="resize"){maxWidthInCSS=parseFloat($this.attr("bigfoot-max-width"));$mainWrap=$this.find(".bigfoot-footnote__wrapper");maxWidth=maxWidthInCSS;if(maxWidthInCSS<=1){relativeToWidth=(function(){var jq,userSpecifiedRelativeElWidth;userSpecifiedRelativeElWidth=10000;if(settings.maxWidthRelativeTo){jq=$(settings.maxWidthRelativeTo);if(jq.length>0){userSpecifiedRelativeElWidth=jq.outerWidth()}} +return Math.min(window.innerWidth,userSpecifiedRelativeElWidth)})();maxWidth=relativeToWidth*maxWidthInCSS} +maxWidth=Math.min(maxWidth,$this.find(".bigfoot-footnote__content").outerWidth()+1);$mainWrap.css("max-width",maxWidth+"px");$this.css({left:(-roomLeft.leftRelative*maxWidth+parseFloat($button.css("margin-left"))+$button.outerWidth()/2)+"px"});positionTooltip($this,roomLeft.leftRelative)} +if(parseInt($this.outerHeight())<$this.find(".bigfoot-footnote__content")[0].scrollHeight){return $this.addClass("is-scrollable")}})}};positionTooltip=function($popover,leftRelative){var $tooltip;if(leftRelative==null){leftRelative=0.5} +$tooltip=$popover.find(".bigfoot-footnote__tooltip");if($tooltip.length>0){$tooltip.css("left",""+(leftRelative*100)+"%")}};roomCalc=function($el){var elHeight,elLeftMargin,elWidth,leftRoom,topRoom,w;elLeftMargin=parseFloat($el.css("margin-left"));elWidth=parseFloat($el.outerWidth())-elLeftMargin;elHeight=parseFloat($el.outerHeight());w=viewportDetails();topRoom=$el.offset().top-w.scrollY+elHeight/2;leftRoom=$el.offset().left-w.scrollX+elWidth/2;return{topRoom:topRoom,bottomRoom:w.height-topRoom,leftRoom:leftRoom,rightRoom:w.width-leftRoom,leftRelative:leftRoom/w.width,topRelative:topRoom/w.height}};viewportDetails=function(){var $window;$window=$(window);return{width:window.innerWidth,height:window.innerHeight,scrollX:$window.scrollLeft(),scrollY:$window.scrollTop()}};addBreakpoint=function(size,trueCallback,falseCallback,deleteDelay,removeOpen){var falseDefaultPositionSetting,minMax,mqListener,mql,query,s,trueDefaultPositionSetting;if(deleteDelay==null){deleteDelay=settings.popoverDeleteDelay} +if(removeOpen==null){removeOpen=!0} +mql=void 0;minMax=void 0;s=void 0;if(typeof size==="string"){s=size.toLowerCase()==="iphone"?"<320px":size.toLowerCase()==="ipad"?"<768px":size;minMax=s.charAt(0)===">"?"min":s.charAt(0)==="<"?"max":null;query=minMax?"("+minMax+"-width: "+(s.substring(1))+")":s;mql=window.matchMedia(query)}else{mql=size} +if(mql.media&&mql.media==="invalid"){return{added:!1,mq:mql,listener:null}} +trueDefaultPositionSetting=minMax==="min";falseDefaultPositionSetting=minMax==="max";trueCallback=trueCallback||makeDefaultCallbacks(removeOpen,deleteDelay,trueDefaultPositionSetting,function($popover){return $popover.addClass("is-bottom-fixed")});falseCallback=falseCallback||makeDefaultCallbacks(removeOpen,deleteDelay,falseDefaultPositionSetting,function(){});mqListener=function(mq){if(mq.matches){trueCallback(removeOpen,bigfoot)}else{falseCallback(removeOpen,bigfoot)}};mql.addListener(mqListener);mqListener(mql);settings.breakpoints[size]={added:!0,mq:mql,listener:mqListener};return settings.breakpoints[size]};makeDefaultCallbacks=function(removeOpen,deleteDelay,position,callback){return function(removeOpen,bigfoot){var $closedPopovers;$closedPopovers=void 0;if(removeOpen){$closedPopovers=bigfoot.close();bigfoot.updateSetting("activateCallback",callback)} +return setTimeout((function(){bigfoot.updateSetting("positionContent",position);if(removeOpen){return bigfoot.activate($closedPopovers)}}),deleteDelay)}};removeBreakpoint=function(target,callback){var b,breakpoint,mq,mqFound;mq=null;b=void 0;mqFound=!1;if(typeof target==="string"){mqFound=settings.breakpoints[target]!==undefined}else{for(b in settings.breakpoints){if(settings.breakpoints.hasOwnProperty(b)&&settings.breakpoints[b].mq===target){mqFound=!0}}} +if(mqFound){breakpoint=settings.breakpoints[b||target];if(callback){callback({matches:!1})}else{breakpoint.listener({matches:!1})} +breakpoint.mq.removeListener(breakpoint.listener);delete settings.breakpoints[b||target]} +return mqFound};updateSetting=function(newSettings,value){var oldValue,prop;oldValue=void 0;if(typeof newSettings==="string"){oldValue=settings[newSettings];settings[newSettings]=value}else{oldValue={};for(prop in newSettings){if(newSettings.hasOwnProperty(prop)){oldValue[prop]=settings[prop];settings[prop]=newSettings[prop]}}} +return oldValue};getSetting=function(setting){return settings[setting]};$(document).ready(function(){footnoteInit();$(document).on("mouseenter",".bigfoot-footnote__button",buttonHover);$(document).on("touchend click",touchClick);$(document).on("mouseout",".is-hover-instantiated",unhoverFeet);$(document).on("keyup",escapeKeypress);$(window).on("scroll resize",repositionFeet);return $(document).on("gestureend",function(){return repositionFeet()})});bigfoot={removePopovers:removePopovers,close:removePopovers,createPopover:createPopover,activate:createPopover,repositionFeet:repositionFeet,reposition:repositionFeet,addBreakpoint:addBreakpoint,removeBreakpoint:removeBreakpoint,getSetting:getSetting,updateSetting:updateSetting};return bigfoot}})(jQuery)}).call(this) \ No newline at end of file diff --git a/assets/js/lunr/lunr-en.js b/assets/js/lunr/lunr-en.js new file mode 100644 index 000000000..d1400a768 --- /dev/null +++ b/assets/js/lunr/lunr-en.js @@ -0,0 +1,69 @@ +var idx = lunr(function () { + this.field('title') + this.field('excerpt') + this.field('categories') + this.field('tags') + this.ref('id') + + this.pipeline.remove(lunr.trimmer) + + for (var item in store) { + this.add({ + title: store[item].title, + excerpt: store[item].excerpt, + categories: store[item].categories, + tags: store[item].tags, + id: item + }) + } +}); + +$(document).ready(function() { + $('input#search').on('keyup', function () { + var resultdiv = $('#results'); + var query = $(this).val().toLowerCase(); + var result = + idx.query(function (q) { + query.split(lunr.tokenizer.separator).forEach(function (term) { + q.term(term, { boost: 100 }) + if(query.lastIndexOf(" ") != query.length-1){ + q.term(term, { usePipeline: false, wildcard: lunr.Query.wildcard.TRAILING, boost: 10 }) + } + if (term != ""){ + q.term(term, { usePipeline: false, editDistance: 1, boost: 1 }) + } + }) + }); + resultdiv.empty(); + resultdiv.prepend('

'+result.length+' Result(s) found

'); + for (var item in result) { + var ref = result[item].ref; + if(store[ref].teaser){ + var searchitem = + '
'+ + '
'+ + '

'+ + ''+store[ref].title+''+ + '

'+ + '
'+ + ''+ + '
'+ + '

'+store[ref].excerpt.split(" ").splice(0,20).join(" ")+'...

'+ + '
'+ + '
'; + } + else{ + var searchitem = + '
'+ + '
'+ + '

'+ + ''+store[ref].title+''+ + '

'+ + '

'+store[ref].excerpt.split(" ").splice(0,20).join(" ")+'...

'+ + '
'+ + '
'; + } + resultdiv.append(searchitem); + } + }); +}); diff --git a/assets/js/lunr/lunr-gr.js b/assets/js/lunr/lunr-gr.js new file mode 100644 index 000000000..e829362bf --- /dev/null +++ b/assets/js/lunr/lunr-gr.js @@ -0,0 +1,522 @@ +step1list = new Array(); +step1list["ΦΑΓΙΑ"] = "ΦΑ"; +step1list["ΦΑΓΙΟΥ"] = "ΦΑ"; +step1list["ΦΑΓΙΩΝ"] = "ΦΑ"; +step1list["ΣΚΑΓΙΑ"] = "ΣΚΑ"; +step1list["ΣΚΑΓΙΟΥ"] = "ΣΚΑ"; +step1list["ΣΚΑΓΙΩΝ"] = "ΣΚΑ"; +step1list["ΟΛΟΓΙΟΥ"] = "ΟΛΟ"; +step1list["ΟΛΟΓΙΑ"] = "ΟΛΟ"; +step1list["ΟΛΟΓΙΩΝ"] = "ΟΛΟ"; +step1list["ΣΟΓΙΟΥ"] = "ΣΟ"; +step1list["ΣΟΓΙΑ"] = "ΣΟ"; +step1list["ΣΟΓΙΩΝ"] = "ΣΟ"; +step1list["ΤΑΤΟΓΙΑ"] = "ΤΑΤΟ"; +step1list["ΤΑΤΟΓΙΟΥ"] = "ΤΑΤΟ"; +step1list["ΤΑΤΟΓΙΩΝ"] = "ΤΑΤΟ"; +step1list["ΚΡΕΑΣ"] = "ΚΡΕ"; +step1list["ΚΡΕΑΤΟΣ"] = "ΚΡΕ"; +step1list["ΚΡΕΑΤΑ"] = "ΚΡΕ"; +step1list["ΚΡΕΑΤΩΝ"] = "ΚΡΕ"; +step1list["ΠΕΡΑΣ"] = "ΠΕΡ"; +step1list["ΠΕΡΑΤΟΣ"] = "ΠΕΡ"; +step1list["ΠΕΡΑΤΑ"] = "ΠΕΡ"; +step1list["ΠΕΡΑΤΩΝ"] = "ΠΕΡ"; +step1list["ΤΕΡΑΣ"] = "ΤΕΡ"; +step1list["ΤΕΡΑΤΟΣ"] = "ΤΕΡ"; +step1list["ΤΕΡΑΤΑ"] = "ΤΕΡ"; +step1list["ΤΕΡΑΤΩΝ"] = "ΤΕΡ"; +step1list["ΦΩΣ"] = "ΦΩ"; +step1list["ΦΩΤΟΣ"] = "ΦΩ"; +step1list["ΦΩΤΑ"] = "ΦΩ"; +step1list["ΦΩΤΩΝ"] = "ΦΩ"; +step1list["ΚΑΘΕΣΤΩΣ"] = "ΚΑΘΕΣΤ"; +step1list["ΚΑΘΕΣΤΩΤΟΣ"] = "ΚΑΘΕΣΤ"; +step1list["ΚΑΘΕΣΤΩΤΑ"] = "ΚΑΘΕΣΤ"; +step1list["ΚΑΘΕΣΤΩΤΩΝ"] = "ΚΑΘΕΣΤ"; +step1list["ΓΕΓΟΝΟΣ"] = "ΓΕΓΟΝ"; +step1list["ΓΕΓΟΝΟΤΟΣ"] = "ΓΕΓΟΝ"; +step1list["ΓΕΓΟΝΟΤΑ"] = "ΓΕΓΟΝ"; +step1list["ΓΕΓΟΝΟΤΩΝ"] = "ΓΕΓΟΝ"; + +v = "[ΑΕΗΙΟΥΩ]"; +v2 = "[ΑΕΗΙΟΩ]" + +function stemWord(w) { + var stem; + var suffix; + var firstch; + var origword = w; + test1 = new Boolean(true); + + if(w.length < 4) { + return w; + } + + var re; + var re2; + var re3; + var re4; + + re = /(.*)(ΦΑΓΙΑ|ΦΑΓΙΟΥ|ΦΑΓΙΩΝ|ΣΚΑΓΙΑ|ΣΚΑΓΙΟΥ|ΣΚΑΓΙΩΝ|ΟΛΟΓΙΟΥ|ΟΛΟΓΙΑ|ΟΛΟΓΙΩΝ|ΣΟΓΙΟΥ|ΣΟΓΙΑ|ΣΟΓΙΩΝ|ΤΑΤΟΓΙΑ|ΤΑΤΟΓΙΟΥ|ΤΑΤΟΓΙΩΝ|ΚΡΕΑΣ|ΚΡΕΑΤΟΣ|ΚΡΕΑΤΑ|ΚΡΕΑΤΩΝ|ΠΕΡΑΣ|ΠΕΡΑΤΟΣ|ΠΕΡΑΤΑ|ΠΕΡΑΤΩΝ|ΤΕΡΑΣ|ΤΕΡΑΤΟΣ|ΤΕΡΑΤΑ|ΤΕΡΑΤΩΝ|ΦΩΣ|ΦΩΤΟΣ|ΦΩΤΑ|ΦΩΤΩΝ|ΚΑΘΕΣΤΩΣ|ΚΑΘΕΣΤΩΤΟΣ|ΚΑΘΕΣΤΩΤΑ|ΚΑΘΕΣΤΩΤΩΝ|ΓΕΓΟΝΟΣ|ΓΕΓΟΝΟΤΟΣ|ΓΕΓΟΝΟΤΑ|ΓΕΓΟΝΟΤΩΝ)$/; + + if(re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + w = stem + step1list[suffix]; + test1 = false; + } + + re = /^(.+?)(ΑΔΕΣ|ΑΔΩΝ)$/; + + if(re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + w = stem; + + reg1 = /(ΟΚ|ΜΑΜ|ΜΑΝ|ΜΠΑΜΠ|ΠΑΤΕΡ|ΓΙΑΓΙ|ΝΤΑΝΤ|ΚΥΡ|ΘΕΙ|ΠΕΘΕΡ)$/; + + if(!(reg1.test(w))) { + w = w + "ΑΔ"; + } + } + + re2 = /^(.+?)(ΕΔΕΣ|ΕΔΩΝ)$/; + + if(re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + w = stem; + + exept2 = /(ΟΠ|ΙΠ|ΕΜΠ|ΥΠ|ΓΗΠ|ΔΑΠ|ΚΡΑΣΠ|ΜΙΛ)$/; + + if(exept2.test(w)) { + w = w + "ΕΔ"; + } + } + + re3 = /^(.+?)(ΟΥΔΕΣ|ΟΥΔΩΝ)$/; + + if(re3.test(w)) { + var fp = re3.exec(w); + stem = fp[1]; + w = stem; + + exept3 = /(ΑΡΚ|ΚΑΛΙΑΚ|ΠΕΤΑΛ|ΛΙΧ|ΠΛΕΞ|ΣΚ|Σ|ΦΛ|ΦΡ|ΒΕΛ|ΛΟΥΛ|ΧΝ|ΣΠ|ΤΡΑΓ|ΦΕ)$/; + + if(exept3.test(w)) { + w = w + "ΟΥΔ"; + } + } + + re4 = /^(.+?)(ΕΩΣ|ΕΩΝ)$/; + + if(re4.test(w)) { + var fp = re4.exec(w); + stem = fp[1]; + w = stem; + test1 = false; + + exept4 = /^(Θ|Δ|ΕΛ|ΓΑΛ|Ν|Π|ΙΔ|ΠΑΡ)$/; + + if(exept4.test(w)) { + w = w + "Ε"; + } + } + + re = /^(.+?)(ΙΑ|ΙΟΥ|ΙΩΝ)$/; + + if(re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + w = stem; + re2 = new RegExp(v + "$"); + test1 = false; + + if(re2.test(w)) { + w = stem + "Ι"; + } + } + + re = /^(.+?)(ΙΚΑ|ΙΚΟ|ΙΚΟΥ|ΙΚΩΝ)$/; + + if(re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + w = stem; + test1 = false; + + re2 = new RegExp(v + "$"); + exept5 = /^(ΑΛ|ΑΔ|ΕΝΔ|ΑΜΑΝ|ΑΜΜΟΧΑΛ|ΗΘ|ΑΝΗΘ|ΑΝΤΙΔ|ΦΥΣ|ΒΡΩΜ|ΓΕΡ|ΕΞΩΔ|ΚΑΛΠ|ΚΑΛΛΙΝ|ΚΑΤΑΔ|ΜΟΥΛ|ΜΠΑΝ|ΜΠΑΓΙΑΤ|ΜΠΟΛ|ΜΠΟΣ|ΝΙΤ|ΞΙΚ|ΣΥΝΟΜΗΛ|ΠΕΤΣ|ΠΙΤΣ|ΠΙΚΑΝΤ|ΠΛΙΑΤΣ|ΠΟΣΤΕΛΝ|ΠΡΩΤΟΔ|ΣΕΡΤ|ΣΥΝΑΔ|ΤΣΑΜ|ΥΠΟΔ|ΦΙΛΟΝ|ΦΥΛΟΔ|ΧΑΣ)$/; + + if((exept5.test(w)) || (re2.test(w))) { + w = w + "ΙΚ"; + } + } + + re = /^(.+?)(ΑΜΕ)$/; + re2 = /^(.+?)(ΑΓΑΜΕ|ΗΣΑΜΕ|ΟΥΣΑΜΕ|ΗΚΑΜΕ|ΗΘΗΚΑΜΕ)$/; + if(w == "ΑΓΑΜΕ") { + w = "ΑΓΑΜ"; + } + + if(re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + w = stem; + test1 = false; + } + + if(re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + w = stem; + test1 = false; + + exept6 = /^(ΑΝΑΠ|ΑΠΟΘ|ΑΠΟΚ|ΑΠΟΣΤ|ΒΟΥΒ|ΞΕΘ|ΟΥΛ|ΠΕΘ|ΠΙΚΡ|ΠΟΤ|ΣΙΧ|Χ)$/; + + if(exept6.test(w)) { + w = w + "ΑΜ"; + } + } + + re2 = /^(.+?)(ΑΝΕ)$/; + re3 = /^(.+?)(ΑΓΑΝΕ|ΗΣΑΝΕ|ΟΥΣΑΝΕ|ΙΟΝΤΑΝΕ|ΙΟΤΑΝΕ|ΙΟΥΝΤΑΝΕ|ΟΝΤΑΝΕ|ΟΤΑΝΕ|ΟΥΝΤΑΝΕ|ΗΚΑΝΕ|ΗΘΗΚΑΝΕ)$/; + + if(re3.test(w)) { + var fp = re3.exec(w); + stem = fp[1]; + w = stem; + test1 = false; + + re3 = /^(ΤΡ|ΤΣ)$/; + + if(re3.test(w)) { + w = w + "ΑΓΑΝ"; + } + } + + if(re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + w = stem; + test1 = false; + + re2 = new RegExp(v2 + "$"); + exept7 = /^(ΒΕΤΕΡ|ΒΟΥΛΚ|ΒΡΑΧΜ|Γ|ΔΡΑΔΟΥΜ|Θ|ΚΑΛΠΟΥΖ|ΚΑΣΤΕΛ|ΚΟΡΜΟΡ|ΛΑΟΠΛ|ΜΩΑΜΕΘ|Μ|ΜΟΥΣΟΥΛΜ|Ν|ΟΥΛ|Π|ΠΕΛΕΚ|ΠΛ|ΠΟΛΙΣ|ΠΟΡΤΟΛ|ΣΑΡΑΚΑΤΣ|ΣΟΥΛΤ|ΤΣΑΡΛΑΤ|ΟΡΦ|ΤΣΙΓΓ|ΤΣΟΠ|ΦΩΤΟΣΤΕΦ|Χ|ΨΥΧΟΠΛ|ΑΓ|ΟΡΦ|ΓΑΛ|ΓΕΡ|ΔΕΚ|ΔΙΠΛ|ΑΜΕΡΙΚΑΝ|ΟΥΡ|ΠΙΘ|ΠΟΥΡΙΤ|Σ|ΖΩΝΤ|ΙΚ|ΚΑΣΤ|ΚΟΠ|ΛΙΧ|ΛΟΥΘΗΡ|ΜΑΙΝΤ|ΜΕΛ|ΣΙΓ|ΣΠ|ΣΤΕΓ|ΤΡΑΓ|ΤΣΑΓ|Φ|ΕΡ|ΑΔΑΠ|ΑΘΙΓΓ|ΑΜΗΧ|ΑΝΙΚ|ΑΝΟΡΓ|ΑΠΗΓ|ΑΠΙΘ|ΑΤΣΙΓΓ|ΒΑΣ|ΒΑΣΚ|ΒΑΘΥΓΑΛ|ΒΙΟΜΗΧ|ΒΡΑΧΥΚ|ΔΙΑΤ|ΔΙΑΦ|ΕΝΟΡΓ|ΘΥΣ|ΚΑΠΝΟΒΙΟΜΗΧ|ΚΑΤΑΓΑΛ|ΚΛΙΒ|ΚΟΙΛΑΡΦ|ΛΙΒ|ΜΕΓΛΟΒΙΟΜΗΧ|ΜΙΚΡΟΒΙΟΜΗΧ|ΝΤΑΒ|ΞΗΡΟΚΛΙΒ|ΟΛΙΓΟΔΑΜ|ΟΛΟΓΑΛ|ΠΕΝΤΑΡΦ|ΠΕΡΗΦ|ΠΕΡΙΤΡ|ΠΛΑΤ|ΠΟΛΥΔΑΠ|ΠΟΛΥΜΗΧ|ΣΤΕΦ|ΤΑΒ|ΤΕΤ|ΥΠΕΡΗΦ|ΥΠΟΚΟΠ|ΧΑΜΗΛΟΔΑΠ|ΨΗΛΟΤΑΒ)$/; + + if((re2.test(w)) || (exept7.test(w))) { + w = w + "ΑΝ"; + } + } + + re3 = /^(.+?)(ΕΤΕ)$/; + re4 = /^(.+?)(ΗΣΕΤΕ)$/; + + if(re4.test(w)) { + var fp = re4.exec(w); + stem = fp[1]; + w = stem; + test1 = false; + } + + if(re3.test(w)) { + var fp = re3.exec(w); + stem = fp[1]; + w = stem; + test1 = false; + + re3 = new RegExp(v2 + "$"); + exept8 = /(ΟΔ|ΑΙΡ|ΦΟΡ|ΤΑΘ|ΔΙΑΘ|ΣΧ|ΕΝΔ|ΕΥΡ|ΤΙΘ|ΥΠΕΡΘ|ΡΑΘ|ΕΝΘ|ΡΟΘ|ΣΘ|ΠΥΡ|ΑΙΝ|ΣΥΝΔ|ΣΥΝ|ΣΥΝΘ|ΧΩΡ|ΠΟΝ|ΒΡ|ΚΑΘ|ΕΥΘ|ΕΚΘ|ΝΕΤ|ΡΟΝ|ΑΡΚ|ΒΑΡ|ΒΟΛ|ΩΦΕΛ)$/; + exept9 = /^(ΑΒΑΡ|ΒΕΝ|ΕΝΑΡ|ΑΒΡ|ΑΔ|ΑΘ|ΑΝ|ΑΠΛ|ΒΑΡΟΝ|ΝΤΡ|ΣΚ|ΚΟΠ|ΜΠΟΡ|ΝΙΦ|ΠΑΓ|ΠΑΡΑΚΑΛ|ΣΕΡΠ|ΣΚΕΛ|ΣΥΡΦ|ΤΟΚ|Υ|Δ|ΕΜ|ΘΑΡΡ|Θ)$/; + + if((re3.test(w)) || (exept8.test(w)) || (exept9.test(w))) { + w = w + "ΕΤ"; + } + } + + re = /^(.+?)(ΟΝΤΑΣ|ΩΝΤΑΣ)$/; + + if(re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + w = stem; + test1 = false; + + exept10 = /^(ΑΡΧ)$/; + exept11 = /(ΚΡΕ)$/; + if(exept10.test(w)) { + w = w + "ΟΝΤ"; + } + if(exept11.test(w)) { + w = w + "ΩΝΤ"; + } + } + + re = /^(.+?)(ΟΜΑΣΤΕ|ΙΟΜΑΣΤΕ)$/; + + if(re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + w = stem; + test1 = false; + + exept11 = /^(ΟΝ)$/; + + if(exept11.test(w)) { + w = w + "ΟΜΑΣΤ"; + } + } + + re = /^(.+?)(ΕΣΤΕ)$/; + re2 = /^(.+?)(ΙΕΣΤΕ)$/; + + if(re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + w = stem; + test1 = false; + + re2 = /^(Π|ΑΠ|ΣΥΜΠ|ΑΣΥΜΠ|ΑΚΑΤΑΠ|ΑΜΕΤΑΜΦ)$/; + + if(re2.test(w)) { + w = w + "ΙΕΣΤ"; + } + } + + if(re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + w = stem; + test1 = false; + + exept12 = /^(ΑΛ|ΑΡ|ΕΚΤΕΛ|Ζ|Μ|Ξ|ΠΑΡΑΚΑΛ|ΑΡ|ΠΡΟ|ΝΙΣ)$/; + + if(exept12.test(w)) { + w = w + "ΕΣΤ"; + } + } + + re = /^(.+?)(ΗΚΑ|ΗΚΕΣ|ΗΚΕ)$/; + re2 = /^(.+?)(ΗΘΗΚΑ|ΗΘΗΚΕΣ|ΗΘΗΚΕ)$/; + + if(re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + w = stem; + test1 = false; + } + + if(re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + w = stem; + test1 = false; + + exept13 = /(ΣΚΩΛ|ΣΚΟΥΛ|ΝΑΡΘ|ΣΦ|ΟΘ|ΠΙΘ)$/; + exept14 = /^(ΔΙΑΘ|Θ|ΠΑΡΑΚΑΤΑΘ|ΠΡΟΣΘ|ΣΥΝΘ|)$/; + + if((exept13.test(w)) || (exept14.test(w))) { + w = w + "ΗΚ"; + } + } + + re = /^(.+?)(ΟΥΣΑ|ΟΥΣΕΣ|ΟΥΣΕ)$/; + + if(re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + w = stem; + test1 = false; + + exept15 = /^(ΦΑΡΜΑΚ|ΧΑΔ|ΑΓΚ|ΑΝΑΡΡ|ΒΡΟΜ|ΕΚΛΙΠ|ΛΑΜΠΙΔ|ΛΕΧ|Μ|ΠΑΤ|Ρ|Λ|ΜΕΔ|ΜΕΣΑΖ|ΥΠΟΤΕΙΝ|ΑΜ|ΑΙΘ|ΑΝΗΚ|ΔΕΣΠΟΖ|ΕΝΔΙΑΦΕΡ|ΔΕ|ΔΕΥΤΕΡΕΥ|ΚΑΘΑΡΕΥ|ΠΛΕ|ΤΣΑ)$/; + exept16 = /(ΠΟΔΑΡ|ΒΛΕΠ|ΠΑΝΤΑΧ|ΦΡΥΔ|ΜΑΝΤΙΛ|ΜΑΛΛ|ΚΥΜΑΤ|ΛΑΧ|ΛΗΓ|ΦΑΓ|ΟΜ|ΠΡΩΤ)$/; + + if((exept15.test(w)) || (exept16.test(w))) { + w = w + "ΟΥΣ"; + } + } + + re = /^(.+?)(ΑΓΑ|ΑΓΕΣ|ΑΓΕ)$/; + + if(re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + w = stem; + test1 = false; + + exept17 = /^(ΨΟΦ|ΝΑΥΛΟΧ)$/; + exept20 = /(ΚΟΛΛ)$/; + exept18 = /^(ΑΒΑΣΤ|ΠΟΛΥΦ|ΑΔΗΦ|ΠΑΜΦ|Ρ|ΑΣΠ|ΑΦ|ΑΜΑΛ|ΑΜΑΛΛΙ|ΑΝΥΣΤ|ΑΠΕΡ|ΑΣΠΑΡ|ΑΧΑΡ|ΔΕΡΒΕΝ|ΔΡΟΣΟΠ|ΞΕΦ|ΝΕΟΠ|ΝΟΜΟΤ|ΟΛΟΠ|ΟΜΟΤ|ΠΡΟΣΤ|ΠΡΟΣΩΠΟΠ|ΣΥΜΠ|ΣΥΝΤ|Τ|ΥΠΟΤ|ΧΑΡ|ΑΕΙΠ|ΑΙΜΟΣΤ|ΑΝΥΠ|ΑΠΟΤ|ΑΡΤΙΠ|ΔΙΑΤ|ΕΝ|ΕΠΙΤ|ΚΡΟΚΑΛΟΠ|ΣΙΔΗΡΟΠ|Λ|ΝΑΥ|ΟΥΛΑΜ|ΟΥΡ|Π|ΤΡ|Μ)$/; + exept19 = /(ΟΦ|ΠΕΛ|ΧΟΡΤ|ΛΛ|ΣΦ|ΡΠ|ΦΡ|ΠΡ|ΛΟΧ|ΣΜΗΝ)$/; + + if(((exept18.test(w)) || (exept19.test(w))) && !((exept17.test(w)) || (exept20.test(w)))) { + w = w + "ΑΓ"; + } + } + + re = /^(.+?)(ΗΣΕ|ΗΣΟΥ|ΗΣΑ)$/; + + if(re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + w = stem; + test1 = false; + + exept21 = /^(Ν|ΧΕΡΣΟΝ|ΔΩΔΕΚΑΝ|ΕΡΗΜΟΝ|ΜΕΓΑΛΟΝ|ΕΠΤΑΝ)$/; + + if(exept21.test(w)) { + w = w + "ΗΣ"; + } + } + + re = /^(.+?)(ΗΣΤΕ)$/; + + if(re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + w = stem; + test1 = false; + + exept22 = /^(ΑΣΒ|ΣΒ|ΑΧΡ|ΧΡ|ΑΠΛ|ΑΕΙΜΝ|ΔΥΣΧΡ|ΕΥΧΡ|ΚΟΙΝΟΧΡ|ΠΑΛΙΜΨ)$/; + + if(exept22.test(w)) { + w = w + "ΗΣΤ"; + } + } + + re = /^(.+?)(ΟΥΝΕ|ΗΣΟΥΝΕ|ΗΘΟΥΝΕ)$/; + + if(re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + w = stem; + test1 = false; + + exept23 = /^(Ν|Ρ|ΣΠΙ|ΣΤΡΑΒΟΜΟΥΤΣ|ΚΑΚΟΜΟΥΤΣ|ΕΞΩΝ)$/; + + if(exept23.test(w)) { + w = w + "ΟΥΝ"; + } + } + + re = /^(.+?)(ΟΥΜΕ|ΗΣΟΥΜΕ|ΗΘΟΥΜΕ)$/; + + if(re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + w = stem; + test1 = false; + + exept24 = /^(ΠΑΡΑΣΟΥΣ|Φ|Χ|ΩΡΙΟΠΛ|ΑΖ|ΑΛΛΟΣΟΥΣ|ΑΣΟΥΣ)$/; + + if(exept24.test(w)) { + w = w + "ΟΥΜ"; + } + } + + re = /^(.+?)(ΜΑΤΑ|ΜΑΤΩΝ|ΜΑΤΟΣ)$/; + re2 = /^(.+?)(Α|ΑΓΑΤΕ|ΑΓΑΝ|ΑΕΙ|ΑΜΑΙ|ΑΝ|ΑΣ|ΑΣΑΙ|ΑΤΑΙ|ΑΩ|Ε|ΕΙ|ΕΙΣ|ΕΙΤΕ|ΕΣΑΙ|ΕΣ|ΕΤΑΙ|Ι|ΙΕΜΑΙ|ΙΕΜΑΣΤΕ|ΙΕΤΑΙ|ΙΕΣΑΙ|ΙΕΣΑΣΤΕ|ΙΟΜΑΣΤΑΝ|ΙΟΜΟΥΝ|ΙΟΜΟΥΝΑ|ΙΟΝΤΑΝ|ΙΟΝΤΟΥΣΑΝ|ΙΟΣΑΣΤΑΝ|ΙΟΣΑΣΤΕ|ΙΟΣΟΥΝ|ΙΟΣΟΥΝΑ|ΙΟΤΑΝ|ΙΟΥΜΑ|ΙΟΥΜΑΣΤΕ|ΙΟΥΝΤΑΙ|ΙΟΥΝΤΑΝ|Η|ΗΔΕΣ|ΗΔΩΝ|ΗΘΕΙ|ΗΘΕΙΣ|ΗΘΕΙΤΕ|ΗΘΗΚΑΤΕ|ΗΘΗΚΑΝ|ΗΘΟΥΝ|ΗΘΩ|ΗΚΑΤΕ|ΗΚΑΝ|ΗΣ|ΗΣΑΝ|ΗΣΑΤΕ|ΗΣΕΙ|ΗΣΕΣ|ΗΣΟΥΝ|ΗΣΩ|Ο|ΟΙ|ΟΜΑΙ|ΟΜΑΣΤΑΝ|ΟΜΟΥΝ|ΟΜΟΥΝΑ|ΟΝΤΑΙ|ΟΝΤΑΝ|ΟΝΤΟΥΣΑΝ|ΟΣ|ΟΣΑΣΤΑΝ|ΟΣΑΣΤΕ|ΟΣΟΥΝ|ΟΣΟΥΝΑ|ΟΤΑΝ|ΟΥ|ΟΥΜΑΙ|ΟΥΜΑΣΤΕ|ΟΥΝ|ΟΥΝΤΑΙ|ΟΥΝΤΑΝ|ΟΥΣ|ΟΥΣΑΝ|ΟΥΣΑΤΕ|Υ|ΥΣ|Ω|ΩΝ)$/; + + if(re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + w = stem + "ΜΑ"; + } + + if((re2.test(w)) && (test1)) { + var fp = re2.exec(w); + stem = fp[1]; + w = stem; + + } + + re = /^(.+?)(ΕΣΤΕΡ|ΕΣΤΑΤ|ΟΤΕΡ|ΟΤΑΤ|ΥΤΕΡ|ΥΤΑΤ|ΩΤΕΡ|ΩΤΑΤ)$/; + + if(re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + w = stem; + } + + return w; +}; + +var greekStemmer = function (token) { + return token.update(function (word) { + return stemWord(word); + }) +} + +var idx = lunr(function () { + this.field('title') + this.field('excerpt') + this.field('categories') + this.field('tags') + this.ref('id') + + this.pipeline.remove(lunr.trimmer) + this.pipeline.add(greekStemmer) + this.pipeline.remove(lunr.stemmer) + + for (var item in store) { + this.add({ + title: store[item].title, + excerpt: store[item].excerpt, + categories: store[item].categories, + tags: store[item].tags, + id: item + }) + } +}); + +$(document).ready(function() { + $('input#search').on('keyup', function () { + var resultdiv = $('#results'); + var query = $(this).val().toLowerCase(); + var result = + idx.query(function (q) { + query.split(lunr.tokenizer.separator).forEach(function (term) { + q.term(term, { boost: 100 }) + if(query.lastIndexOf(" ") != query.length-1){ + q.term(term, { usePipeline: false, wildcard: lunr.Query.wildcard.TRAILING, boost: 10 }) + } + if (term != ""){ + q.term(term, { usePipeline: false, editDistance: 1, boost: 1 }) + } + }) + }); + resultdiv.empty(); + resultdiv.prepend('

'+result.length+' Result(s) found

'); + for (var item in result) { + var ref = result[item].ref; + if(store[ref].teaser){ + var searchitem = + '
'+ + '
'+ + '

'+ + ''+store[ref].title+''+ + '

'+ + '
'+ + ''+ + '
'+ + '

'+store[ref].excerpt.split(" ").splice(0,20).join(" ")+'...

'+ + '
'+ + '
'; + } + else{ + var searchitem = + '
'+ + '
'+ + '

'+ + ''+store[ref].title+''+ + '

'+ + '

'+store[ref].excerpt.split(" ").splice(0,20).join(" ")+'...

'+ + '
'+ + '
'; + } + resultdiv.append(searchitem); + } + }); +}); diff --git a/assets/js/lunr/lunr-store.js b/assets/js/lunr/lunr-store.js new file mode 100644 index 000000000..bba8ffae5 --- /dev/null +++ b/assets/js/lunr/lunr-store.js @@ -0,0 +1,811 @@ +var store = [{ + "title": "Apple Watch ADHD", + "excerpt":"I’ve been wanting to write about some ways that my smartwatch has helped me deal with the fact that I perceive time differently than most neurotypical people. It’s an example of what Aimi Hamraie has called “ADHD technologies.”1 Timers I use the timer function often—especially when I’m doing any kind...","categories": [], + "tags": [], + "url": "/notes/ADHD-tech/apple-watch-ADHD", + "teaser": null + },{ + "title": "About ADHD technologies", + "excerpt":"I recently saw this tweet by Aimi Hamraie, with the hashtag ADHDtechnologies: Have been getting lots of questions about how to be an academic with ADHD. Different for all of us but here is one of my #adhdtechnologies: a flip-top notebook with running to do lists that I keep on...","categories": [], + "tags": [], + "url": "/notes/ADHD-tech/about-ADHD-technologies", + "teaser": null + },{ + "title": "ADHD tech", + "excerpt":" Pinned ADHD tech notes 📌 About ADHD technologies :seedling: All ADHD tech items 📌 About ADHD technologies :seedling: Apple Watch ADHD :herb: ","categories": [], + "tags": [], + "url": "/notes/ADHD-tech/index", + "teaser": null + },{ + "title": "ADHD", + "excerpt":" All ADHD items There's nothing here yet! ","categories": [], + "tags": [], + "url": "/notes/ADHD/index", + "teaser": null + },{ + "title": "Accessibility", + "excerpt":" All Accessibility items Math Accessibility :seedling: ","categories": [], + "tags": [], + "url": "/notes/Accessibility/index", + "teaser": null + },{ + "title": "Keywords", + "excerpt":"All Keywords folders Pinned Keywords notes All Keywords items There's nothing here yet! ","categories": [], + "tags": [], + "url": "/notes/Keywords/index", + "teaser": null + },{ + "title": "Listening", + "excerpt":"Welcome to my Listening notes! All Listening items There's nothing here yet! ","categories": [], + "tags": [], + "url": "/notes/Listening/index", + "teaser": null + },{ + "title": "Approaches", + "excerpt":" All Approaches items Casey Boyle's …something like a reading ethics… :seedling: Rhetorical Précis :seedling: ","categories": [], + "tags": [], + "url": "/notes/Note-taking/Approaches/index", + "teaser": null + },{ + "title": "Literature Notes in Dendron", + "excerpt":"I’ve been refining a system for taking literature notes in Dendron, which complements keeping citations with Zotero. My systems remain perpetually in flux, but this is at least my most current write-up, if not my most current approach. Dendron is an extension for the text editor VS Code. If you...","categories": [], + "tags": [], + "url": "/notes/Note-taking/Dendron/literature-notes-dendron", + "teaser": null + },{ + "title": "Beginning to Use Dendron", + "excerpt":"What is Dendron? Dendron lets you create—and more importantly, organize—plain text notes in VS Code. It not only lets you link between notes like a wiki, it makes notes findable through a tree view and customizable, hierarchical organization. I’m such a fan that I switched from Atom to VS Code...","categories": [], + "tags": [], + "url": "/notes/Note-taking/Dendron/beginning-to-use-dendron", + "teaser": null + },{ + "title": "Casey Boyle's …something like a reading ethics…", + "excerpt":"This strategy for reading is meant to build better habits of reading, as well as better note-taking. It’s a nice complement to a rhetorical-precis, but more open-ended. Casey Boyle’s “…something like a reading ethics…” Casey’s post on his approach (via the WaybackMachine) explains it in excellent detail. It’s very much...","categories": [], + "tags": [], + "url": "/notes/Note-taking/Approaches/casey-boyle-something-like-reading-ethics", + "teaser": null + },{ + "title": "Rhetorical Précis", + "excerpt":"One of the most frustrating things about reading widely is the situation where you’ve read something, but can’t recall any details or situate that piece among the other things you’ve read. As with Casey Boyle’s “…something like a reading ethics…,” writing a rhetorical précis is a great, brief method for...","categories": [], + "tags": [], + "url": "/notes/Note-taking/Approaches/rhetorical-precis", + "teaser": null + },{ + "title": "Dendron", + "excerpt":" All Dendron items Beginning to Use Dendron :seedling: Literature Notes in Dendron :seedling: Task Tracking in Dendron :seedling: ","categories": [], + "tags": [], + "url": "/notes/Note-taking/Dendron/index", + "teaser": null + },{ + "title": "Task Tracking in Dendron", + "excerpt":"My notes in Dendron are an unruly, monstrous hybrid of a bullet journal, a log, a set of resources, and other information. And I like it like that! They’re a continuation of the monthly planning files I used before Dendron came along. So if I use Dendron as a combination...","categories": [], + "tags": [], + "url": "/notes/Note-taking/Dendron/task-tracking-in-dendron", + "teaser": null + },{ + "title": "Beginning to Use Obsidian", + "excerpt":"What is Obsidian? Well, it’s complicated. And so are my feelings. The simple version is that Obsidian is an app that lets you write linked notes, mostly in Markdown format, and can render dynamically-updated sections of those notes. This last piece—the dynamic updating—is what makes it compelling and complicated. The...","categories": [], + "tags": [], + "url": "/notes/Note-taking/Obsidian/beginning-to-use-obsidian", + "teaser": null + },{ + "title": "Obsidian", + "excerpt":" All Obsidian items Beginning to Use Obsidian :seedling: Obsidian Plugins :herb: Obsidian Tasks Plugin :herb: ","categories": [], + "tags": [], + "url": "/notes/Note-taking/Obsidian/index", + "teaser": null + },{ + "title": "Note taking", + "excerpt":"All Note taking folders Approaches Dendron Obsidian All Note taking items Casey Boyle's …something like a reading ethics… :seedling: Rhetorical Précis :seedling: Beginning to Use Dendron :seedling: Literature Notes in Dendron :seedling: Task Tracking in Dendron :seedling: Beginning to Use Obsidian :seedling: Obsidian Plugins :herb: Obsidian Tasks Plugin :herb: ","categories": [], + "tags": [], + "url": "/notes/Note-taking/index", + "teaser": null + },{ + "title": "Pedagogy", + "excerpt":" All Pedagogy items There's nothing here yet! ","categories": [], + "tags": [], + "url": "/notes/Pedagogy/index", + "teaser": null + },{ + "title": "Articles", + "excerpt":" All my notes on articles I've read Actively Engaging Students in Asynchronous Online Classes. :herb: All my reading notes on articles by year There's nothing here yet! ","categories": [], + "tags": [], + "url": "/notes/Reading/Articles/index", + "teaser": null + },{ + "title": "Capital is Dead. Is This Something Worse?", + "excerpt":"Wark asks us to think about information less like Marxists and more like Marx. ","categories": [], + "tags": [], + "url": "/notes/Reading/Books/wark-capital-is-dead", + "teaser": null + },{ + "title": "Obsidian Plugins", + "excerpt":"Assumed audience People at least passably familiar with Obsidian. See my other notes on Obsidian for more context. What’s the Big Deal about Obsidian Plugins? One of the best—and most anxiety-producing, from the viewpoint of long-term stability—aspects of Obsidian is how the developers have opened up the app to community...","categories": [], + "tags": [], + "url": "/notes/Note-taking/Obsidian/obsidian-plugins", + "teaser": null + },{ + "title": "Obsidian Tasks Plugin", + "excerpt":"Assumed audience People at least passably familiar with Obsidian. See my other notes on Obsidian for more context. What is the Tasks plugin? Originally written by Martin Schenck and now expertly maintained by Clare Macrae, the Tasks plugin is the thing that ultimately convinced me to switch from Dendron to...","categories": [], + "tags": [], + "url": "/notes/Note-taking/Obsidian/obsidian-tasks-plugin-patterns", + "teaser": null + },{ + "title": "Modernist Informatics: Literature, Information, and the State", + "excerpt":"Purdon examines modernist fiction to trace how writers experienced information culture as a disturbing interruption and governmental intrusion. ","categories": [], + "tags": [], + "url": "/notes/Reading/Books/purdon-modernist-informatics", + "teaser": null + },{ + "title": "Actively Engaging Students in Asynchronous Online Classes.", + "excerpt":"From the paper’s own abstract: This paper suggests a three-pronged approach for conceptualizing active learning in the online asynchronous class: the creation of an architecture of engagement in the online classroom, the use of web-based tools in addition to the learning management system, and a re-imagining of discussion boards as...","categories": [], + "tags": [], + "url": "/notes/Reading/Articles/riggs-and-linder-actively-engaging-students", + "teaser": null + },{ + "title": "Policing the Crisis: Mugging, the State, and Law and Order", + "excerpt":"Hall and cowriters provide a classic analysis of the rhetoric of a moral panic. ","categories": [], + "tags": [], + "url": "/notes/Reading/Books/hall-policing-the-crisis", + "teaser": null + },{ + "title": "Books", + "excerpt":"All my notes on books I've read Capital is Dead. Is This Something Worse? :herb: Policing the Crisis: Mugging, the State, and Law and Order :herb: Overwhelmed: Literature, Aesthetics, and the Nineteenth-Century Information Revolution :herb: Modernist Informatics: Literature, Information, and the State :herb: All my reading notes on books by...","categories": [], + "tags": [], + "url": "/notes/Reading/Books/index", + "teaser": null + },{ + "title": "Overwhelmed: Literature, Aesthetics, and the Nineteenth-Century Information Revolution", + "excerpt":"Lee explores the history of how various cultural formations around literature and information grew through the 19th Century Information Revolution. ","categories": [], + "tags": [], + "url": "/notes/Reading/Books/lee-overwhelmed", + "teaser": null + },{ + "title": "Reading", + "excerpt":"All Reading folders Articles Books All notes on what I've read Capital is Dead. Is This Something Worse? :herb: Overwhelmed: Literature, Aesthetics, and the Nineteenth-Century Information Revolution :herb: Policing the Crisis: Mugging, the State, and Law and Order :herb: Actively Engaging Students in Asynchronous Online Classes. :herb: Modernist Informatics: Literature,...","categories": [], + "tags": [], + "url": "/notes/Reading/index", + "teaser": null + },{ + "title": "Snippets", + "excerpt":" All Snippets items Information Informatics :seedling: ","categories": [], + "tags": [], + "url": "/notes/Snippets/index", + "teaser": null + },{ + "title": "Information Informatics", + "excerpt":"Here are some insightful snippets about “information” & “informatics” that I’ve found. 2020 Purdon, Modernist Informatics Modernist Informatics: Literature, Information, and the State In the company kept by the word—public service and business, agency and control—we can begin to discern the outline of a modern understanding of information as a...","categories": [], + "tags": [], + "url": "/notes/Snippets/information-informatics", + "teaser": null + },{ + "title": "Jekyll", + "excerpt":" All Jekyll items Jekyll Guides :seedling: ","categories": [], + "tags": [], + "url": "/notes/Technology/Jekyll/index", + "teaser": null + },{ + "title": "Social Media", + "excerpt":" All Social Media items Mastodon Apps :seedling: Mastodon Settings :seedling: ","categories": [], + "tags": [], + "url": "/notes/Technology/Social-Media/index", + "teaser": null + },{ + "title": "VS Code", + "excerpt":" All VS Code items Daybreak Theme :herb: VS Code Snippets :herb: VS Code Spellcheck Squiggles :herb: VS Code note :seedling: ","categories": [], + "tags": [], + "url": "/notes/Technology/VS-Code/index", + "teaser": null + },{ + "title": "VS Code note", + "excerpt":"Here’s where I’ll detail aspects of how I set up and use of VS Code, which I adopted so I could use Dendron in particular. You can learn more about how I use Dendron in literature notes in dendron. ","categories": [], + "tags": [], + "url": "/notes/Technology/VS-Code/vs-code", + "teaser": null + },{ + "title": "Daybreak Theme", + "excerpt":"Horizon, then Daybreak I’m a big fan of dark themes. I’ve been using variants of Horizon for quite a while now in VS Code (as you can read about in vs code note), since I like the overall warmth of the theme’s color palette. Unfortunately, the person who initially designed...","categories": [], + "tags": [], + "url": "/notes/Technology/VS-Code/daybreak-theme", + "teaser": null + },{ + "title": "Math Accessibility", + "excerpt":"Assumed audience People relatively—or almost entirely—new to web publishing I’ve lately done some work to improve the accessibility of math notation (equations, symbols, etc.) for users of screen readers online, particularly for the creation of open educational resources (OER). It’s been an unexpectedly engrossing investigation, so I figured I’d share...","categories": [], + "tags": [], + "url": "/notes/Accessibility/math-a11y", + "teaser": null + },{ + "title": "Mastodon Apps", + "excerpt":"I’ve been using Mastodon for a while. Apparently at least since April of 2017‽?! I tend to use Mastodon on my phone at least as much as I do through a browser. At various times I’ve used Metatext, Mast, Amaroq, and a tab of Safari pinned to appear as its...","categories": [], + "tags": [], + "url": "/notes/Technology/Social-Media/mastodon-apps", + "teaser": null + },{ + "title": "Mastodon Settings", + "excerpt":"This isn’t trying to be comprehensive, or even an overview. This is just me writing up some notes, as if I were explaining the settings to someone in my family. I’m not checking every setting to see if my recommendation varies from the default. If I remember, I’ll probably refine...","categories": [], + "tags": [], + "url": "/notes/Technology/Social-Media/mastodon-settings", + "teaser": null + },{ + "title": "Jekyll Guides", + "excerpt":"I really enjoy using Jekyll, enough that I’d recommend it to anyone who is both looking to make their own site and has the time or inclination to do more “behind the scenes” than necessary for site made with WordPress or Squarespace. Jekyll’s own documentation is one of the most...","categories": [], + "tags": [], + "url": "/notes/Technology/Jekyll/jekyll-guides", + "teaser": null + },{ + "title": "VS Code Snippets", + "excerpt":"This is one of my longest notes. Please don’t forget that the Table of Contents can help you jump to a particular section! I’m a fan of keeping a Bullet Journal in a text editor, as I’ve written about in task-tracking-in-dendron. A Digital Bullet Journal might not seem like a...","categories": [], + "tags": [], + "url": "/notes/Technology/VS-Code/vs-code-snippets", + "teaser": null + },{ + "title": "VS Code Spellcheck Squiggles", + "excerpt":"There are a number of spellchecking extensions available for VS Code. I realized recently that I’d disabled the spellcheck I installed because of how distracting I found VS Code’s default squiggly lines. So I set about making them less intrusive, but still easily perceptible. Step 1: Check the Notification Class...","categories": [], + "tags": [], + "url": "/notes/Technology/VS-Code/vs-code-spellcheck-squiggles", + "teaser": null + },{ + "title": "Technology", + "excerpt":"All Technology folders Jekyll Social Media VS Code All Technology items Jekyll Guides :seedling: Mastodon Apps :seedling: Mastodon Settings :seedling: Daybreak Theme :herb: VS Code Snippets :herb: VS Code Spellcheck Squiggles :herb: VS Code note :seedling: ","categories": [], + "tags": [], + "url": "/notes/Technology/index", + "teaser": null + },{ + "title": "Emerging Notes", + "excerpt":"Welcome to my notes! This is my digital garden—a loosely tended succulent collection. Pathways of thought represented via pixels, all perpetually in process. Show yourself around! :seedling: Emerging Notes _notes/ADHD-tech/about-ADHD-technologies.md :seedling: _notes/Accessibility/math-a11y.md :seedling: _notes/Note-taking/Approaches/casey-boyle-something-like-reading-ethics.md :seedling: _notes/Note-taking/Approaches/rhetorical-precis.md :seedling: _notes/Note-taking/Dendron/beginning-to-use-dendron.md :seedling: _notes/Note-taking/Dendron/literature-notes-dendron.md :seedling: _notes/Note-taking/Dendron/task-tracking-in-dendron.md :seedling: _notes/Note-taking/Obsidian/beginning-to-use-obsidian.md :seedling: _notes/Snippets/information-informatics.md :seedling: _notes/Technology/Jekyll/jekyll-guides.md :seedling: _notes/Technology/Social-Media/mastodon-apps.md...","categories": [], + "tags": [], + "url": "/notes/emerging-notes", + "teaser": null + },{ + "title": "Notes Index", + "excerpt":"Welcome to my notes! This is my digital garden—a loosely tended succulent collection. Pathways of thought represented via pixels, all perpetually in process. Show yourself around! All folders ADHD ADHD-tech Accessibility Keywords Listening Note-taking Pedagogy Reading Snippets Technology :house_with_garden: All my notes _notes/ADHD-tech/about-ADHD-technologies.md :seedling: _notes/ADHD-tech/apple-watch-ADHD.md :herb: _notes/Accessibility/math-a11y.md :seedling: _notes/Note-taking/Approaches/casey-boyle-something-like-reading-ethics.md :seedling:...","categories": [], + "tags": [], + "url": "/notes/index", + "teaser": null + },{ + "title": "New Site", + "excerpt":"Complicating, circulating…new site, new site. Operating, generating…new site, new site. Thanks for coming by, and for indulging my Depeche Mode reference.1 This new site is decidedly in an early state of becoming, as I figure out how to use Jekyll and this particular theme. I’ll probably use this for more...","categories": [], + "tags": ["meta"], + "url": "/new-site", + "teaser": null + },{ + "title": "Test One", + "excerpt":" If everything is ready from the dark side of the moon… …play the five tones. ","categories": [], + "tags": ["meta"], + "url": "/test-one", + "teaser": null + },{ + "title": "New Directions in Information Fluency", + "excerpt":"On April 4th & 5th, I drove up to Augustana College in Rock Island, Illinois with my friend & colleague Katherine Ahnberg for the New Directions in Information Literacy conference at Augustana College. As Katherine recently wrote, we presented a brief history of humanities computing (digital humanities or DH), an...","categories": ["blog"], + "tags": ["conferences","presentations","digital humanities"], + "url": "/blog/new-directions-in-information-fluency", + "teaser": null + },{ + "title": "Bigfoot Spotting and Other Jekyll Adventures", + "excerpt":"Here’s a test of Bigfoot.js, a rather awesome addition to the web. 1 (edit: It’ll remain elusive, see footnote #2.)2 (edit № 2: I’ve gotten it to work, as of 2015-05-31! It wasn’t an issue with Jekyll or GitHub Pages, but rather with my understanding of how Jekyll & GitHub...","categories": [], + "tags": ["meta","tech tools"], + "url": "/bigfoot-spotting", + "teaser": null + },{ + "title": "Review of Online Archive of California", + "excerpt":"This post was originally an assignment for John Walsh’s “Z652 Digital Libraries” course at IU-Bloomington. A fantastic clearing house of information about Californian collections, the Online Archive of California serves as a centralized set of links to and descriptions of an enormous number of collections from various archives, historical societies,...","categories": [], + "tags": ["digital humanities","coursework"], + "url": "/review-of-online-archive-of-california", + "teaser": null + },{ + "title": "Software Carpentry Workshop Reflections", + "excerpt":"Welcome to the Command Line It wasn’t quite Tron: I jumped into the world of computing for two days while taking a Software Carpentry workshop and it turned out highly illuminating without being threatening. This post aims to summarize what I learned & its relevance to librarians and/or digital humanities...","categories": [], + "tags": ["digital humanities"], + "url": "/software-carpentry-workshop-reflections", + "teaser": null + },{ + "title": "“Paper,” “Planned Obsolescence,” and Digital Libraries", + "excerpt":"This post was originally an assignment for John Walsh’s “Z652 Digital Libraries” course at IU-Bloomington. Two talks given at IU in the last month offer insights for digital libraries, one benefiting from direct experimentation with forms of scholarly communication and sustained analysis of academic practices, while the other’s scope provides...","categories": [], + "tags": ["digital libraries","coursework"], + "url": "/paper-planned-obsolescence-and-digital-libraries", + "teaser": null + },{ + "title": "#critlib Chatty Critical Librarianship on Twitter", + "excerpt":"Here’s a post I wrote for Hack Libary School on critical librarianship and the #critlib chats on Twitter. I also discuss student-led interests groups, metacognition, and Bloom’s Taxonomy of educational objectives. There’s even a brief bibliography of anthologies to check out for more on critical librarianship. ","categories": [], + "tags": ["critlib chats","hack library school"], + "url": "/critlib-chatty-critical-librarianship-on-twitter", + "teaser": null + },{ + "title": "How Do You Take Notes (or Markdown and Bullet Journals)", + "excerpt":"Here’s a post I wrote for Hack Library School discussing Markdown and the Bullet Journal system for note-taking. Markdown is a simplified way of writing html, and happens to also be what I use when writing this site through Jekyll and GitHub Pages. Bullet Journals are a system not for...","categories": [], + "tags": ["hack library school","markdown","meta","notetaking"], + "url": "/how-do-you-take-notes-or-markdown-and-bullet-journals", + "teaser": null + },{ + "title": "Freire and Critical Librarianship", + "excerpt":"This post is for Week One of MOOC MOOC: Critical Pedagogy. Processes. Processes, all the way down. That’s what strikes me most about the first three chapters of Freire’s The Pedagogy of the Oppressed: his insistence on processes of becoming, of history, of liberation, and of course, of pedagogy through...","categories": [], + "tags": ["critlib chats","pedagogy","moocmooc","critical theory","featured"], + "url": "/freire-and-critical-librarianship", + "teaser": null + },{ + "title": "#critlib Makerspaces", + "excerpt":"Friend or Foe? I recently had the pleasure of moderating a #critlib chat on Makerspaces. These spaces have been enjoying increasing popularity in libraries, demonstrating how libraries function as far more than warehouses for documents. At their best, makerspaces help community members learn by doing, regardless of whether these spaces...","categories": [], + "tags": ["critlib chats","pedagogy","makerspaces"], + "url": "/critlib-makerspaces", + "teaser": null + },{ + "title": "Wojnarowicz on a Sphere", + "excerpt":":warning: :construction: This post is currently under construction. The actual project grew out of an assignment for John Walsh’s “Z652 Digital Libraries” course at IU-Bloomington. When I learned that we would be doing a mapping project for John Walsh’s Digital Humanities course, two artists quickly sprang to mind due to...","categories": [], + "tags": ["coursework","digital humanities","visual culture"], + "url": "/wojnarowicz-on-a-sphere", + "teaser": null + },{ + "title": "Learning Subjectives", + "excerpt":"This post is for Week One of #rhizo15. Here’s something I constantly rediscover, sometimes painfully: although I’m a capable writer, I’m predisposed toward research. This orientation seems both a boon and a hindrance as an aspiring academic librarian. Research calls to me in large part because of its rhizomatic nature—I...","categories": [], + "tags": ["rhizo15","neutrality","pedagogy","digital humanities"], + "url": "/learning-subjectives", + "teaser": null + },{ + "title": "Hack Quirk Your Presentations", + "excerpt":"A new post of mine recently went up at Hack Library School. It’s about a simple technique that I’ve noticed can help instruction sessions or resource demonstrations feel a bit more exciting and memorable: highlighting a quirky result or aspect of the interface. As a bonus, I talk about Batman,...","categories": [], + "tags": ["hack library school","instructional design & tools","digital humanities"], + "url": "/del-hack-del-quirk-your-presentations", + "teaser": null + },{ + "title": "Everything Counts in Affective Amounts", + "excerpt":"This post is for Week Two of #rhizo15. Typing Hands Type What They Can Over the last week I’ve effectively been teaching myself Zurb’s Foundation website framework as part of using it to make a prototype website for an information architecture course. Participating in #rhizo15 has primed me to really...","categories": [], + "tags": ["rhizo15","digital humanities","tech tools"], + "url": "/everything-counts-in-affective-amounts", + "teaser": null + },{ + "title": "#Rhizo15 Week Three: "Content is People"", + "excerpt":"This post is for Week Three of #rhizo15: “The Myth of Content.” Even though I’m writing this during Week Five, I’m trying to put my thoughts out a little quicker than usual in this post, in keeping with my post from Week One. For Week Three, Dave asked: So what...","categories": [], + "tags": ["rhizo15","pedagogy","critical information literacy"], + "url": "/rhizo15-week-three", + "teaser": null + },{ + "title": "Quick Thoughts on Method & Knowledge Practices in Arts & Humanities", + "excerpt":"Earlier today I saw a few #critlib threads swirling around on Twitter—here’s one and here’s another. The ones that caught my eyes mostly had to do with how open #critlib twitter chats & their participants seem to critique or criticism, the extent to which critical theory has to do with...","categories": [], + "tags": ["critlib chats","pedagogy","method"], + "url": "/quick-thoughts-on-method", + "teaser": null + },{ + "title": "Presentation Alternatives: Reveal.js", + "excerpt":"Here’s a post I wrote for Hack Library School talking about my experience with the Reveal.js JavaScript presentation framework. Not only does it hew to my goal of choosing open-source tools over proprietary formats whenever feasible, its functionality and inherent ability to make presentations shareable on the web make it...","categories": [], + "tags": ["presentations","tech tools","pedagogy","critical theory","a11y","hack library school"], + "url": "/reveal-js-hack-library-school", + "teaser": null + },{ + "title": "Critical Hot Potato! aka #Rhizo15 Week Four", + "excerpt":"This post responds to the prompt for Week Four of #rhizo15: “How Do We Teach Rhizomatically?”. For Week Four, Dave asked: “I think there is value in the ‘course’ in the sense of the eventedness that it represents. It’s a chance for people to come together and focus on a...","categories": [], + "tags": ["rhizo15","critlib chats","critical theory"], + "url": "/critpotato-rhizo15-week-four", + "teaser": null + },{ + "title": "All Hail Cloud Storage", + "excerpt":"I wrote for Hack Library School about why & how I use Dropbox. What I didn’t include were particular recommendations for other programs that integrate nicely with Dropbox. Perhaps it’s my college dj training that makes me super hesitant to encourage people to buy a particular program or product when...","categories": [], + "tags": ["hack library school","markdown","meta","tech tools"], + "url": "/all-hail-cloud-storage", + "teaser": null + },{ + "title": "Weekly Assemblage 2015 Week 36", + "excerpt":"#radlibchat “Librarians’ views on critical theories and critical practices” On Tuesday, 2015-09-01, there was a great #radlibchat focused on librarians’ views of critical theories and critical practices. Hosted by the Radical Librarians Collective, this recently-begun set of chats take place once a month. Much like #critlib chats, they suggest readings...","categories": ["weekly-assemblage"], + "tags": ["critical theory","privacy"], + "url": "/weekly-assemblage/weekly-assemblage-2015-week-36", + "teaser": null + },{ + "title": "Weekly Assemblage 2015 Week 37", + "excerpt":"#critlib chat on Information & Migrant Populations Tuesday, 2015-09-08, saw a #critlib Twitter chat on information & migrant populations. Amiably—and admirably—moderated by Greg Bemb, this chat took a broad approach to considering the information and access needs of different migrant communities. Participants considered international migration, urbanization within a particular country,...","categories": ["weekly-assemblage"], + "tags": ["critlib chats","privacy","cfp","critical race studies"], + "url": "/weekly-assemblage/weekly-assemblage-2015-week-37", + "teaser": null + },{ + "title": "Weekly Assemblage 2015 Week 38", + "excerpt":"I’m posting this week’s write-up a bit late since this week was basically spent furiously packing and then on the road, moving from Bloomington, Indiana all the way to Boise, Idaho! This week we’ve got photos of that trip, plus reflections on a book I read before the trip. Westward,...","categories": ["weekly-assemblage"], + "tags": ["critical theory"], + "url": "/weekly-assemblage/weekly-assemblage-2015-week-38", + "teaser": null + },{ + "title": "Weekly Assemblage 2015 Week 39", + "excerpt":"I’m publishing this week’s write-up rather late—but I do want to document the experience of moving somewhat, for other future librarians who move! Couple new library cards to really help me feel welcomed! #westwardidaho A photo posted by Ryan Randall (@foureyedsoul) on Sep 26, 2015 at 5:07pm PDT   This...","categories": ["weekly-assemblage"], + "tags": ["pedagogy","critical information literacy"], + "url": "/weekly-assemblage/weekly-assemblage-2015-week-39", + "teaser": null + },{ + "title": "This Is Not a Pipette: Bringing Humanities Methods into LIS Programs", + "excerpt":"I recently wrote a post for Hack Library School on examples of how we might break humanities methodologies to bear on information studies. In part, I wrote this in response to the recent statement by the editors of College & Research Libraries that they are looking for papers that use...","categories": [], + "tags": ["hack library school","critical theory"], + "url": "/this-is-not-a-pipette", + "teaser": null + },{ + "title": "Weekly Assemblage 2015 Week 40", + "excerpt":"Here’s another decidedly-after-the-fact post—who knew that moving could upend so many things? This week I began my position as the Instruction and Outreach Librarian at the College of Western Idaho! Peculiarly enough, my starting date aligned with the annual conference of the Idaho state library association. Rather than have me...","categories": ["weekly-assemblage"], + "tags": ["conferences"], + "url": "/weekly-assemblage/weekly-assemblage-2015-week-40", + "teaser": null + },{ + "title": "Weekly Assemblage 2015 Week 41", + "excerpt":"#critlib chat on Scientific Objectivity Rory Litwin of Library Juice Press recently moderated a #critlib Twitter chat on neutrality and objectivity in scientific information. Referencing the “Scientific Objectivity” article by Julian Reiss and Jan Sprenger from the excellent, open-access Stanford Encyclopedia of Philosophy, this chat dealt with the tension between...","categories": ["weekly-assemblage"], + "tags": ["critlib chats","critical information literacy","critical race studies"], + "url": "/weekly-assemblage/weekly-assemblage-2015-week-41", + "teaser": null + },{ + "title": "Weekly Assemblage 2015 Week 42", + "excerpt":"Crissinger’s “Being ‘Human’ in the Classroom” Live! Real! Human! Sarah Crissinger’s recent “Being ‘Human’ in the Classroom: A Case for Personal Testimony in Pedagogy” post at ACRLog does a wonderful job of giving specifics on how librarians can use our personal experiences with the research process while instructing students. Maybe...","categories": ["weekly-assemblage"], + "tags": ["critical information literacy","pedagogy"], + "url": "/weekly-assemblage/weekly-assemblage-2015-week-42", + "teaser": null + },{ + "title": "Weekly Assemblage 2015 Week 43", + "excerpt":"We’ve had two notable projects at our library this week: working on a “Five Year Vision of the Library” document and preparing for the Halloween outreach events. I’ll post photos of the outreach things next week, but this week I’ll just mention that a shared, editable Google Doc has worked...","categories": ["weekly-assemblage"], + "tags": ["critlib chats","gender","librar* history"], + "url": "/weekly-assemblage/weekly-assemblage-2015-week-43", + "teaser": null + },{ + "title": "Weekly Assemblage 2015 Week 44", + "excerpt":"This Is Halloween A couple of the CWI Library student workers suggested Once Upon a Time as a theme for our Halloween decorations, and we ended up embracing it enthusiastically. I admittedly had to do some ahem “binge watching research” on Netflix, but our approach to the theme said that...","categories": ["weekly-assemblage"], + "tags": ["outreach"], + "url": "/weekly-assemblage/weekly-assemblage-2015-week-44", + "teaser": null + },{ + "title": "Weekly Assemblage 2015 Week 45", + "excerpt":"Read of the Week As an Instruction & Outreach Librarian, one of the things I’m currently trying to do is revamp our fliers and other materials that broadcast what we can do for instructors. Our current materials were written before the ACRL Framework came out, so I’m trying to update...","categories": ["weekly-assemblage"], + "tags": ["critical information literacy","meta"], + "url": "/weekly-assemblage/weekly-assemblage-2015-week-45", + "teaser": null + },{ + "title": "WA 2015 Week 46 Massumi and North", + "excerpt":"Reads of the Week! “Undigesting Deleuze” by Brian Massumi, accessible at LA Review of Books “The Idea of a Writing Center” by Stephen M. North in College English v46 n5 p433-46 Sep 1984 This has been a week of reading things that help me frame librarianship in new ways. The...","categories": ["weekly-assemblage"], + "tags": ["critical theory","infrastucture","critical information literacy"], + "url": "/weekly-assemblage/WA-2015-week-46-Massumi-and-North", + "teaser": null + },{ + "title": "WA 2015 Week 47 Schoofs and Battista", + "excerpt":"Reads this Week How did I forget about the LOEX Quarterly’s articles being effectively open access after a year? This means it’s a great place to look for articles to share, such as for #critlib discussions. These two are both short enough that I won’t really reprise much of them...","categories": ["weekly-assemblage"], + "tags": ["critical information literacy"], + "url": "/weekly-assemblage/wa-2015-week-47", + "teaser": null + },{ + "title": "WA 2015 Week 48 Fister, Kurz, Vecchione", + "excerpt":"Reads this Week It’s 2015-12-12 and I’m still looking at the rough draft of this post languishing unpublished. So instead of trying to annotate why I like these so much, I’m just going to grab a quote that I hope entices you to read each of them. Clearly, I’m still...","categories": ["weekly-assemblage"], + "tags": ["makerspaces"], + "url": "/weekly-assemblage/wa-2015-week-48", + "teaser": null + },{ + "title": "WA 2015 Week 49 Holman, Mattern, Barron, Students", + "excerpt":"Reads This Week It’s 2015-12-12 and I’m still looking at the rough draft of this post languishing unpublished. So instead of heavily annotating why I like these so much, I’m just going to grab a quote that I hope entices you to read each of them. Clearly, I’m still figuring...","categories": ["weekly-assemblage"], + "tags": ["makerspaces","infrastucture"], + "url": "/weekly-assemblage/wa-2015-week-49", + "teaser": null + },{ + "title": "critlib #feelings", + "excerpt":"This is a post for the upcoming #critlib chat: “#feelings”. Why are you a critical librarian? Libraries exist as spaces for transformation and change. Without being convinced about the effects of library access on his own life, Andrew Carnegie almost certainly wouldn’t have helped fund so many libraries with free...","categories": [], + "tags": ["critlib chats","critical theory","featured"], + "url": "/critlib-feelings", + "teaser": null + },{ + "title": "Weekly Whaaa…?", + "excerpt":"Having written these for a while, I think I’ve finally got an inkling of what they are do & how to describe them! tl;dr version For the tl:dr version, I want to share things in a form that accommodates things outside of well-crafted shorter essays, “proper” blog posts, or posts...","categories": ["weekly-assemblage"], + "tags": ["meta"], + "url": "/weekly-assemblage/weekly-whaaa", + "teaser": null + },{ + "title": "WA 2016 Week 01: #critlib chat on information resources & incarcerated people", + "excerpt":"Weekly Whaaa…? #critlib chat on Information Resources & Incarcerated People On Monday, 2016-01-04, I was lucky to co-moderate a #critlib chat with Seattle’s Books to Prisoners on information resources & incarcerated people. With my previous knowledge of prison libraries only being a bit of volunteering for Bloomington, Indiana’s Midwest Pages...","categories": ["weekly-assemblage"], + "tags": ["critlib chats","moocmooc","tech tools"], + "url": "/weekly-assemblage/wa-2016-week-01", + "teaser": null + },{ + "title": "WA 2016 Week 02: Giroux on Neutrality", + "excerpt":"Weekly Whaaa…? Giroux’s “Schooling and the Culture of Positivism: Notes on the Death of History” Over the holidays I read Giroux’s On Critical Pedagogy, a collection of some older and new essays. The one that particularly sticks with me is “Schooling and the Culture of Positivism: Notes on the Death...","categories": ["weekly-assemblage"], + "tags": ["critical theory","neutrality"], + "url": "/weekly-assemblage/wa-2016-week-02", + "teaser": null + },{ + "title": "WA 2016 Week 03: Du Bois & scientific sociology, #WOCinTechChat stock photos, LIS Mental Health Week", + "excerpt":"Weekly Whaaa…? “The Case for Scholarly Reparations” and #critlib scholarly communication A great read starting off this week was Julian Go’s The Case for Scholarly Reparations, a review essay on Aldon Morris’ The Scholar Denied. The main argument—seemingly shared by Morris and Go—is that Du Bois’ Atlanta School began scientific...","categories": ["weekly-assemblage"], + "tags": ["scholarly communication","librar* history","outreach"], + "url": "/weekly-assemblage/wa-2016-week-03", + "teaser": null + },{ + "title": "WA 2016 Week 04: Library Privacy", + "excerpt":"Weekly Whaaa…? I’m doing a few of these quite a bit after the fact. ACLU Idaho & Alison Macrina at Meridian Public Library These two presenters were stellar. Here’s just a bit of my notes from each. If you want notes in their entirety, feel free to contact me to...","categories": ["weekly-assemblage"], + "tags": ["privacy"], + "url": "/weekly-assemblage/wa-2016-week-04", + "teaser": null + },{ + "title": "WA 2016 Week 05: #critlib chat on Patience and Impatience; Alison Hicks' LibGuides: Pedagogy to Oppress?", + "excerpt":"Weekly Whaaa…? I’m doing a few of these quite after the fact. One of the highlights of this week was the #critlib chat on Patience and Impatience, moderated by Lisa Hinchliffe , Cecily Walker, and April Hathcock. It was “a chance for everyone to talk about the struggles we face...","categories": ["weekly-assemblage"], + "tags": ["critlib chats","pedagogy"], + "url": "/weekly-assemblage/wa-2016-week-05", + "teaser": null + },{ + "title": "WA 2016 Week 06: THATCampBoiseState 2016", + "excerpt":"Weekly Whaaa…? Here’s another post I’m doing well after the fact. The highlight of this week was attending #THATCampBSU, an unconference around The Humanities and Technology. I met an awful lot of cool people ranging from local activists to coders to librarians. Thankfully, almost everyone there seemed to wear multiple...","categories": ["weekly-assemblage"], + "tags": ["conferences"], + "url": "/weekly-assemblage/wa-2016-week-06", + "teaser": null + },{ + "title": "WA 2016 Week 07: Tools for Thinking", + "excerpt":"Weekly Whaaa…? Here’s another post I’m writing well after the fact. This week I taught a ton of information literacy/Library 101-style sessions. Tools for Thinking The main “new” things for me this week were that I found a few great handouts to use in these sessions—these are the type of...","categories": ["weekly-assemblage"], + "tags": ["tech tools","tools for thinking"], + "url": "/weekly-assemblage/wa-2016-week-07", + "teaser": null + },{ + "title": "WA 2016 Week 08: CLAPS2016 Critical Librarianship and Pedagogy Symposium", + "excerpt":"Weekly Whaaa…? This week was :clap: :clap: :clap: #CLAPS2016, more formally known as the Critical Librarianship and Pedagogy Symposium at the University of Arizona in Tucson. It was fantastic meeting in person with folks I’ve conversed with online. I’m still mentally processing all of the different sessions, so here’s a...","categories": ["weekly-assemblage"], + "tags": ["conferences"], + "url": "/weekly-assemblage/wa-2016-week-08", + "teaser": null + },{ + "title": "WA 2016 Week 12: DERAIL, Site Updates", + "excerpt":"Weekly Whaaa…? Although I aspire to write these “Weekly Assemblage” posts every week, in the spirit of a sort of weekly Library Day in the Life Project, that clearly doesn’t always happen. The last few weeks have been busy in various ways, so I’ll just do a quick round-up of...","categories": ["weekly-assemblage"], + "tags": ["conferences","meta"], + "url": "/weekly-assemblage/wa-2016-week-12", + "teaser": null + },{ + "title": "WA 2016 Week 14: Intro to #critlib chat, Reveal.js image alt tags", + "excerpt":"Weekly Whaaa…? Intro to #critlib chat Courtney Boudreau hosted the second intro to #critlib chat, having co-hosted one earlier with Annie Pho. Here’s a link to the Storify made by Alice Prael. A3. It would be cool to see #critlib extend across all of LAM. Fascinating stuff is going on...","categories": ["weekly-assemblage"], + "tags": ["critlib chats","makerspaces","a11y"], + "url": "/weekly-assemblage/wa-2016-week-14", + "teaser": null + },{ + "title": "WA 2016 Week 15: UC Davis Wants Some Scrubs", + "excerpt":"Weekly Whaaa…? Radical Librarians #radlibchat This week, the Radical Librarians hosted a chat with April Hathcock. UC Davis wants some scrubs UC Davis paid consultants at least $175,000 for attempts to scrub the Internet of links about their pepper spraying of nonviolent student protestors. someones going to write about how...","categories": ["weekly-assemblage"], + "tags": ["dissent","critical librarianship history"], + "url": "/weekly-assemblage/wa-2016-week-15", + "teaser": null + },{ + "title": "WA 2016 Week 16: SWILA 2016; Joacim Hansson on Chantal Mouffe", + "excerpt":"Weekly Whaaa…? SWILA UnConference 2016 The Southwest Idaho Library UnConference, held at the Collister branch of the Boise Public Library, went wonderfully! Here’s what people tweeted about it. For me, the (unplanned!) outreach session was a highlight, as well as the very planned user experience one. Read Hansson on Mouffe...","categories": ["weekly-assemblage"], + "tags": ["conferences"], + "url": "/weekly-assemblage/wa-2016-week-16", + "teaser": null + },{ + "title": "WA 2016 Week 17: Research Notebook is Go!", + "excerpt":"Weekly Whaaa…? Having kicked the idea around for a while, I finally took a couple evenings to work out how I’ll attempt an Open Humanities Research Notebook. Behold: it lives! As I say over there, I realized that I often feel a need to wrap posts up tidily here somehow....","categories": ["weekly-assemblage"], + "tags": ["meta"], + "url": "/weekly-assemblage/wa-2016-week-17", + "teaser": null + },{ + "title": "WA 2016 Week 18: First Reading Notes and #critlib on Emotional Labor", + "excerpt":"Weekly Whaaa…? Reading Notes I posted the first reading notes on my open research notebook, as well as starting to read the Information Literacy chapter from Handbook for Community College Librarians by Michael A. Crumpton and Nora J. Bird. #critlib on Emotional Labor There was a #critlib chat focused on...","categories": ["weekly-assemblage"], + "tags": ["instruction assessment","critlib chats"], + "url": "/weekly-assemblage/wa-2016-week-18", + "teaser": null + },{ + "title": "WA 2016 Week 19: SJL Seattle and Lots of Great Readings", + "excerpt":"Weekly Whaaa…? Social Justice and Libraries Student-Run Open Conference in Seattle SJL Seattle happened on 2016-05-14. Congratulations to the student organizers, Reed Garber-Pearson, Allison Reibel, and Marisa Petrich on what appears to have been a fantastic day! I considered driving over from Boise, but ultimately wasn’t able to make it....","categories": ["weekly-assemblage"], + "tags": ["conferences","critical librarianship","critical librarianship history","librar* history"], + "url": "/weekly-assemblage/wa-2016-week-19", + "teaser": null + },{ + "title": "WA 2016 Week 27: Weekly Roundup and Website Housekeeping", + "excerpt":"Weekly Whaaa…? Weekly Roundup I read a lot this last week or so—too much to annotate each in depth. So I’ll just quickly post links to all of these and suggest you go check them out: Rebecca Halpern and Chimene Tucker’s “Leveraging Adult Learning Theory with Online Tutorials” article gave...","categories": ["weekly-assemblage"], + "tags": ["tools for thinking"], + "url": "/weekly-assemblage/wa-2016-week-27", + "teaser": null + },{ + "title": "WA 2016 Week 31: Design Things Galore", + "excerpt":"Weekly Whaaa…? Design Things, Here, There, and Everywhere It’s been a while since I’ve had time to post one of these. I realized that there were a few design related things in my “I should post about this” file, so here they are! The buttons templates and tutorials from Librarian...","categories": ["weekly-assemblage"], + "tags": ["design","meta"], + "url": "/weekly-assemblage/wa-2016-week-31", + "teaser": null + },{ + "title": "WA 2016 Week 32: Lots of Linkage; Comments Have Arrived", + "excerpt":"Weekly Whaaa…? Lots of Linkage Here’s a handful of links that I either shared or meant to share on Twitter: Rachael Neu linked to Richard Van Heertum’s “How Objective is Objectivity?” article in UCLA InterActions journal recently in a list-serv. I’m eagerly awaiting reading that article, but in the meanwhile...","categories": ["weekly-assemblage"], + "tags": ["meta"], + "url": "/weekly-assemblage/wa-2016-week-32", + "teaser": null + },{ + "title": "Critical Reflection #critlib chat", + "excerpt":"Here’s a post in preparation for the “Critical Reflection” #critlib chat moderated by Lisa Hubbell. Lisa Hubbell’s commitment to making this chat about critical reflection more accessible to people for whom Twitter isn’t optimal inspired me enough to want to do a “seeding” blog post of my own. The topic...","categories": [], + "tags": ["critlib chats","tools for thinking"], + "url": "/critical-reflection", + "teaser": null + },{ + "title": "WA 2017 Week 01: Journaling, Pedagogy, and Advocating for our Patrons", + "excerpt":"Weekly Whaaa…? Craig Eley’s Jekyll logbook theme Perhaps it was due to participating in the #critlib chat on reflection, moderated by Lisa Hubbell? Perhaps it was because I miss using DayOne, which I slowly abandoned after they changed how they sync the files? Perhaps it’s just that I’ve gotten really...","categories": ["weekly-assemblage"], + "tags": ["meta","critlib chats","neutrality","pedagogy"], + "url": "/weekly-assemblage/wa-2017-week-01", + "teaser": null + },{ + "title": "WA 2017 Week 09: Badges, Type, BibTeX", + "excerpt":"Weekly Whaaa…? Emily Ford’s “To badge or not to badge? From ‘yes’ to ‘never again’” “To badge or not to badge? From ‘yes’ to ‘never again’” I really like this article and appreciate Emily Ford’s perspective here. Oddly enough, we’ve gone ahead with a variant of badging at my college...","categories": ["weekly-assemblage"], + "tags": ["badging","tech tools","type"], + "url": "/weekly-assemblage/wa-2017-week-09", + "teaser": null + },{ + "title": "ALA Annual 2018: My Schedule, Our Notes", + "excerpt":"#ALAAC2018 I haven’t been to an Annual ALA Conference yet, so it’ll be interesting to see how my attention can hold up to meeting so many people and hearing so many ideas. I’ve been to a number of smaller conferences, but nothing on this scale. Building from the Critical ALA...","categories": [], + "tags": ["conferences"], + "url": "/my-ala-annual-2018-schedule", + "teaser": null + },{ + "title": "ah, Carl, while you are not safe I am not safe", + "excerpt":"Braiding Together a Few Strands of Thought This post was prompted by a few things I saw on Mastodon and Twitter, plus having wanted to write something during LIS Mental Health Week for a few years now. I started drafting it as a short thread that brought in the social...","categories": [], + "tags": ["neurodiversity","LISMentalHealth","a11y"], + "url": "/while-you-are-not-safe-i-am-not-safe", + "teaser": null + },{ + "title": "Introducing Monthly Signal Boosts", + "excerpt":"What’s This About? It’s pretty clear that my weekly assemblage posts aren’t particularly sustainable, at least at the moment. All the same, I want to get back to regular posts. With these I aim at boosting—sometimes also critiquing—things that I appreciate. Seeing Jessica Schomberg’s Monthly Reading Lists gave me the...","categories": ["monthly-signal-boost"], + "tags": [], + "url": "/monthly-signal-boost/introducing-monthly-signal-boosts", + "teaser": null + },{ + "title": "July 2020 Monthly Signal Boost", + "excerpt":"Monthly What? Podcasts Organizing Ideas Podcast: Episode 20 with Jessica Schomberg Jessica Schomberg talks about their book, other readings they’ve learned from, how workplace improvements for disabled folks will lead to better workplaces for everyone, about relationships and solidarity in library work. It’s a really engaging listen! The Latino Card:...","categories": ["monthly-signal-boost"], + "tags": [], + "url": "/monthly-signal-boost/july-2020-monthly-signal-boost", + "teaser": null + },{ + "title": "SIFT Links", + "excerpt":"Here are some links related to my submission to the “innovative ideas” lightning talk / virtual poster session of the 2020 MOSS Meetup organized by ICfL. The SIFT Moves Introducing SIFT, a Four Moves Acronym, Mike Caulfield’s initial post about the moves Check, Please! Course, an OER textbook with explanations...","categories": [], + "tags": ["conferences","pedagogy"], + "url": "/sift-links", + "teaser": null + },{ + "title": "New note on Apple Watches and ADHD", + "excerpt":"I just published a new note on Apple Watches and ADHD in my digital garden / wonky wiki. It’s one of my first! ","categories": ["notes"], + "tags": [], + "url": "/notes/new-note-on-apple-watch-and-adhd", + "teaser": null + },{ + "title": "August 2020 Monthly Signal Boost", + "excerpt":"Monthly What? 2020 has not been a kind year. This last month has been hectic and at times very overwhelming. Here’s some of what has worked to keep my spirits up. Mindfulness I’ve been trying to get back into mindfulness & meditation practices, since I’d like to more skillfully recognize...","categories": ["monthly-signal-boost"], + "tags": [], + "url": "/monthly-signal-boost/august-2020-monthly-signal-boost", + "teaser": null + },{ + "title": "New note on ADHD technologies", + "excerpt":"I just published a new note on ADHD technologies in my digital garden / wonky wiki. It’s one of my first! ","categories": ["notes"], + "tags": [], + "url": "/notes/new-note-on-adhd-technologies", + "teaser": null + },{ + "title": "New note on reading snippets about Information and Informatics", + "excerpt":"I just published a new note with some snippets about information and informatics in my digital garden / wonky wiki. ","categories": ["notes"], + "tags": [], + "url": "/notes/new-note-on-informatics-readings", + "teaser": null + },{ + "title": "New note on the VS Code editor", + "excerpt":"I’ve just made a new note about the VS Code text editor, and why I like it. ","categories": ["notes"], + "tags": [], + "url": "/notes/new-note-on-vs-code", + "teaser": null + },{ + "title": "New note on keeping literature notes in Dendron", + "excerpt":"I’ve just made a new note about how I keep literature notes in Dendron. ","categories": ["notes"], + "tags": [], + "url": "/notes/new-note-on-keeping-literature-notes-in-dendron", + "teaser": null + },{ + "title": "New note on the Daybreak theme for VS Code", + "excerpt":"I’ve just made a new note about the Daybreak theme for VS Code, and my customizations to it. ","categories": ["notes"], + "tags": [], + "url": "/notes/new-note-on-the-daybreak-theme", + "teaser": null + },{ + "title": "New note on beginning to use Dendron", + "excerpt":"I’ve just made a new note where I’ll keep suggestions for beginning to use Dendron. ","categories": ["notes"], + "tags": [], + "url": "/notes/new-note-beginning-to-use-dendron", + "teaser": null + },{ + "title": "New note on math accessibility", + "excerpt":"I’ve written a new note with what I’ve recently learned about ways to make equations and other math notation more accessible online. ","categories": ["notes"], + "tags": [], + "url": "/notes/new-note-on-math-accessibility", + "teaser": null + },{ + "title": "New note on task tracking in Dendron", + "excerpt":"I just published a new note on how I track tasks in Dendron in my digital garden / wonky wiki. ","categories": ["notes"], + "tags": [], + "url": "/notes/new-note-on-task-tracking-in-dendron", + "teaser": null + },{ + "title": "New note on Mastodon iOS apps", + "excerpt":"I’ve just made a new note where I’ll keep annotated links to particularly useful Jekyll guides. ","categories": ["notes"], + "tags": [], + "url": "/notes/new-note-on-mastodon-ios-apps", + "teaser": null + },{ + "title": "New note on Mastodon Settings", + "excerpt":"I’ve just made a new note where I’ll keep annotated links to particularly useful Jekyll guides. ","categories": ["notes"], + "tags": [], + "url": "/notes/new-note-on-mastodon-settings", + "teaser": null + },{ + "title": "Introducing Blips and Link Rhizomes", + "excerpt":"Here We Go, What’s Our Scenarios? Blips Blog posts feel to me like they should involve a few paragraphs, and probably shouldn’t happen more than once a day. Maybe just a few a week is what feels right for them on my own site. (This feeling is just for my...","categories": ["blips"], + "tags": [], + "url": "/blips/introducing-blips-and-link-rhizomes", + "teaser": null + },{ + "title": "New note on Jekyll Guides", + "excerpt":"I’ve just made a new note where I’ll keep annotated links to particularly useful Jekyll guides. ","categories": ["notes"], + "tags": [], + "url": "/notes/jekyll-guides-note", + "teaser": null + },{ + "title": "Phone to Blog Blip Workflow", + "excerpt":"Couch to Internet With a cat snoozing on my lap and less than 10 minutes before I’m supposed to start watching a new-to-me episode of Star Trek: The Next Generation, the thought occurred to me: how quickly could I make a blog post happen? Long ago I set up Working...","categories": ["blips"], + "tags": [], + "url": "/blips/phone-to-blog-blip-workflow", + "teaser": null + },{ + "title": "New note on Rhetorical Précis", + "excerpt":"I’ve just made a new note about the rhetorical précis format for taking reading notes. ","categories": ["notes"], + "tags": [], + "url": "/notes/new-note-on-rhetorical-precis", + "teaser": null + },{ + "title": "New note on Casey Boyle's …something like a reading ethics…", + "excerpt":"I’ve just made a new note about Casey Boyle’s …something like a reading ethics…, which is a very useful approach to reading and taking notes. ","categories": ["notes"], + "tags": [], + "url": "/notes/new-note-on-casey-boyles-something-like-a-reading-ethics", + "teaser": null + },{ + "title": "Weekly Assemblage for 2023 Week 09", + "excerpt":"Weekly Whaaa…? Daily Notes in Dendron For whatever reason, I’ve been using daily notes in Dendron this week, and it’s been a pleasant and useful addition to my usual practices. Although many people who use tools like Dendron or Obsidian seem to prefer working out of daily notes, I do...","categories": ["weekly-assemblage"], + "tags": [], + "url": "/weekly-assemblage/wa-2023-week-09", + "teaser": null + },{ + "title": "Weekly Assemblage for 2023 Week 10", + "excerpt":"Weekly Whaaa…? Week of Sidequests In many ways, this week has felt like a bundle of sidequests, with little obvious at the end. But hey, some weeks are like that. I ended up spending a lot of time doing spring cleaning of my task notes. FOSS and Crafts Podcasts For...","categories": ["weekly-assemblage"], + "tags": [], + "url": "/weekly-assemblage/wa-2023-week-10", + "teaser": null + },{ + "title": "Weekly Assemblage for 2023 Week 12", + "excerpt":"Weekly Whaaa…? Patterns for VS Code The last couple of weeks I’ve been helping some faculty members create more accessible data tables. That kind of repetitive structure is a great candidate for a code snippet—so I made a few! Here’s the surprisingly long VS Code Snippets note I just wrote...","categories": ["weekly-assemblage"], + "tags": [], + "url": "/weekly-assemblage/wa-2023-week-12", + "teaser": null + },{ + "title": "New note on Snippets and VS Code", + "excerpt":"Last week I made a new note about some snippets I often use, both in VS Code and other places. I’m continuing to update the note with additional snippets. In fact, I just added three about time and dates. ","categories": ["notes"], + "tags": [], + "url": "/notes/new-note-on-snippets-and-vs-code", + "teaser": null + },{ + "title": "New note on Spellcheck Squiggles in VS Code", + "excerpt":"I made a new note about spellcheck squiggles in VS Code, and how to make them just perceptible enough. ","categories": ["notes"], + "tags": [], + "url": "/notes/new-note-on-spellcheck-squiggles-in-vs-code", + "teaser": null + },{ + "title": "Weekly Assemblage for 2023 Week 17", + "excerpt":"Weekly Whaaa…? Wow! This month has kept me busy—so much that I haven’t been updating this weekly. VS Code Snippets and Spellcheck Customizations At the beginning of the month, I made a couple of new notes. One explains some snippets I often use, both in VS Code and other places....","categories": ["weekly-assemblage"], + "tags": [], + "url": "/weekly-assemblage/wa-2023-week-17", + "teaser": null + },{ + "title": "Light Mode in Progress", + "excerpt":"Today—the day after I finished up a “16 weeks condensed into 4” Spanish class—I happened to read some folks on Mastodon talking about light themes on websites. I’ve been wanting to add one to my site for years, my brain apparently wanted a project I could reasonably accomplish make noticeable...","categories": [], + "tags": [], + "url": "/light-mode-in-progress", + "teaser": null + },{ + "title": "I've Been Using Obsidian", + "excerpt":"I’ve been using Obsidian, the app for linked notes. I’ve written a note with some first thoughts, and I’m planning to write more already. ","categories": ["notes"], + "tags": [], + "url": "/notes/beginning-to-use-obsidian", + "teaser": null + },{ + "title": "My Obsidian plugins shortlist", + "excerpt":"Over the weekend, I wrote a note with a short list of the Obsidian plugins that do the most to make it feel like “my” notes. I’m already planning to detail some of these further in separate notes. If that’s somehow your sort of preferred reading, stay tuned! ","categories": ["notes"], + "tags": [], + "url": "/notes/obsidian-plugins", + "teaser": null + },{ + "title": "AcWriMo2023", + "excerpt":"As I recently mentioned on Mastodon, I’m going to try doing Academic Writing Month (aka “AcWriMo”; a fellow traveler of National Novel Writing Month, or “NaNoWriMo”) this year. Here I’m detailing my approach—I’ll likely also update this with my progress throughout the experiment. La Lucha Continúa My most consistent writing...","categories": [], + "tags": [], + "url": "/acwrimo2023", + "teaser": null + },{ + "title": "Obsidian Tasks patterns", + "excerpt":"As I’ve mentioned a few times, I began using Obsidian earlier this year. Ultimately, the Tasks plugin was what convinced me to adopt it, despite my fondness for Dendron and my general hesitations/frustrations about Obsidian. It took quite a bit of delving into the Obsidian Discord forums and subsequent experimentation...","categories": ["notes"], + "tags": [], + "url": "/notes/obsidian-tasks-patterns", + "teaser": null + }] diff --git a/assets/js/lunr/lunr.js b/assets/js/lunr/lunr.js new file mode 100644 index 000000000..6aa370fbc --- /dev/null +++ b/assets/js/lunr/lunr.js @@ -0,0 +1,3475 @@ +/** + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 + * Copyright (C) 2020 Oliver Nightingale + * @license MIT + */ + +;(function(){ + +/** + * A convenience function for configuring and constructing + * a new lunr Index. + * + * A lunr.Builder instance is created and the pipeline setup + * with a trimmer, stop word filter and stemmer. + * + * This builder object is yielded to the configuration function + * that is passed as a parameter, allowing the list of fields + * and other builder parameters to be customised. + * + * All documents _must_ be added within the passed config function. + * + * @example + * var idx = lunr(function () { + * this.field('title') + * this.field('body') + * this.ref('id') + * + * documents.forEach(function (doc) { + * this.add(doc) + * }, this) + * }) + * + * @see {@link lunr.Builder} + * @see {@link lunr.Pipeline} + * @see {@link lunr.trimmer} + * @see {@link lunr.stopWordFilter} + * @see {@link lunr.stemmer} + * @namespace {function} lunr + */ +var lunr = function (config) { + var builder = new lunr.Builder + + builder.pipeline.add( + lunr.trimmer, + lunr.stopWordFilter, + lunr.stemmer + ) + + builder.searchPipeline.add( + lunr.stemmer + ) + + config.call(builder, builder) + return builder.build() +} + +lunr.version = "2.3.9" +/*! + * lunr.utils + * Copyright (C) 2020 Oliver Nightingale + */ + +/** + * A namespace containing utils for the rest of the lunr library + * @namespace lunr.utils + */ +lunr.utils = {} + +/** + * Print a warning message to the console. + * + * @param {String} message The message to be printed. + * @memberOf lunr.utils + * @function + */ +lunr.utils.warn = (function (global) { + /* eslint-disable no-console */ + return function (message) { + if (global.console && console.warn) { + console.warn(message) + } + } + /* eslint-enable no-console */ +})(this) + +/** + * Convert an object to a string. + * + * In the case of `null` and `undefined` the function returns + * the empty string, in all other cases the result of calling + * `toString` on the passed object is returned. + * + * @param {Any} obj The object to convert to a string. + * @return {String} string representation of the passed object. + * @memberOf lunr.utils + */ +lunr.utils.asString = function (obj) { + if (obj === void 0 || obj === null) { + return "" + } else { + return obj.toString() + } +} + +/** + * Clones an object. + * + * Will create a copy of an existing object such that any mutations + * on the copy cannot affect the original. + * + * Only shallow objects are supported, passing a nested object to this + * function will cause a TypeError. + * + * Objects with primitives, and arrays of primitives are supported. + * + * @param {Object} obj The object to clone. + * @return {Object} a clone of the passed object. + * @throws {TypeError} when a nested object is passed. + * @memberOf Utils + */ +lunr.utils.clone = function (obj) { + if (obj === null || obj === undefined) { + return obj + } + + var clone = Object.create(null), + keys = Object.keys(obj) + + for (var i = 0; i < keys.length; i++) { + var key = keys[i], + val = obj[key] + + if (Array.isArray(val)) { + clone[key] = val.slice() + continue + } + + if (typeof val === 'string' || + typeof val === 'number' || + typeof val === 'boolean') { + clone[key] = val + continue + } + + throw new TypeError("clone is not deep and does not support nested objects") + } + + return clone +} +lunr.FieldRef = function (docRef, fieldName, stringValue) { + this.docRef = docRef + this.fieldName = fieldName + this._stringValue = stringValue +} + +lunr.FieldRef.joiner = "/" + +lunr.FieldRef.fromString = function (s) { + var n = s.indexOf(lunr.FieldRef.joiner) + + if (n === -1) { + throw "malformed field ref string" + } + + var fieldRef = s.slice(0, n), + docRef = s.slice(n + 1) + + return new lunr.FieldRef (docRef, fieldRef, s) +} + +lunr.FieldRef.prototype.toString = function () { + if (this._stringValue == undefined) { + this._stringValue = this.fieldName + lunr.FieldRef.joiner + this.docRef + } + + return this._stringValue +} +/*! + * lunr.Set + * Copyright (C) 2020 Oliver Nightingale + */ + +/** + * A lunr set. + * + * @constructor + */ +lunr.Set = function (elements) { + this.elements = Object.create(null) + + if (elements) { + this.length = elements.length + + for (var i = 0; i < this.length; i++) { + this.elements[elements[i]] = true + } + } else { + this.length = 0 + } +} + +/** + * A complete set that contains all elements. + * + * @static + * @readonly + * @type {lunr.Set} + */ +lunr.Set.complete = { + intersect: function (other) { + return other + }, + + union: function () { + return this + }, + + contains: function () { + return true + } +} + +/** + * An empty set that contains no elements. + * + * @static + * @readonly + * @type {lunr.Set} + */ +lunr.Set.empty = { + intersect: function () { + return this + }, + + union: function (other) { + return other + }, + + contains: function () { + return false + } +} + +/** + * Returns true if this set contains the specified object. + * + * @param {object} object - Object whose presence in this set is to be tested. + * @returns {boolean} - True if this set contains the specified object. + */ +lunr.Set.prototype.contains = function (object) { + return !!this.elements[object] +} + +/** + * Returns a new set containing only the elements that are present in both + * this set and the specified set. + * + * @param {lunr.Set} other - set to intersect with this set. + * @returns {lunr.Set} a new set that is the intersection of this and the specified set. + */ + +lunr.Set.prototype.intersect = function (other) { + var a, b, elements, intersection = [] + + if (other === lunr.Set.complete) { + return this + } + + if (other === lunr.Set.empty) { + return other + } + + if (this.length < other.length) { + a = this + b = other + } else { + a = other + b = this + } + + elements = Object.keys(a.elements) + + for (var i = 0; i < elements.length; i++) { + var element = elements[i] + if (element in b.elements) { + intersection.push(element) + } + } + + return new lunr.Set (intersection) +} + +/** + * Returns a new set combining the elements of this and the specified set. + * + * @param {lunr.Set} other - set to union with this set. + * @return {lunr.Set} a new set that is the union of this and the specified set. + */ + +lunr.Set.prototype.union = function (other) { + if (other === lunr.Set.complete) { + return lunr.Set.complete + } + + if (other === lunr.Set.empty) { + return this + } + + return new lunr.Set(Object.keys(this.elements).concat(Object.keys(other.elements))) +} +/** + * A function to calculate the inverse document frequency for + * a posting. This is shared between the builder and the index + * + * @private + * @param {object} posting - The posting for a given term + * @param {number} documentCount - The total number of documents. + */ +lunr.idf = function (posting, documentCount) { + var documentsWithTerm = 0 + + for (var fieldName in posting) { + if (fieldName == '_index') continue // Ignore the term index, its not a field + documentsWithTerm += Object.keys(posting[fieldName]).length + } + + var x = (documentCount - documentsWithTerm + 0.5) / (documentsWithTerm + 0.5) + + return Math.log(1 + Math.abs(x)) +} + +/** + * A token wraps a string representation of a token + * as it is passed through the text processing pipeline. + * + * @constructor + * @param {string} [str=''] - The string token being wrapped. + * @param {object} [metadata={}] - Metadata associated with this token. + */ +lunr.Token = function (str, metadata) { + this.str = str || "" + this.metadata = metadata || {} +} + +/** + * Returns the token string that is being wrapped by this object. + * + * @returns {string} + */ +lunr.Token.prototype.toString = function () { + return this.str +} + +/** + * A token update function is used when updating or optionally + * when cloning a token. + * + * @callback lunr.Token~updateFunction + * @param {string} str - The string representation of the token. + * @param {Object} metadata - All metadata associated with this token. + */ + +/** + * Applies the given function to the wrapped string token. + * + * @example + * token.update(function (str, metadata) { + * return str.toUpperCase() + * }) + * + * @param {lunr.Token~updateFunction} fn - A function to apply to the token string. + * @returns {lunr.Token} + */ +lunr.Token.prototype.update = function (fn) { + this.str = fn(this.str, this.metadata) + return this +} + +/** + * Creates a clone of this token. Optionally a function can be + * applied to the cloned token. + * + * @param {lunr.Token~updateFunction} [fn] - An optional function to apply to the cloned token. + * @returns {lunr.Token} + */ +lunr.Token.prototype.clone = function (fn) { + fn = fn || function (s) { return s } + return new lunr.Token (fn(this.str, this.metadata), this.metadata) +} +/*! + * lunr.tokenizer + * Copyright (C) 2020 Oliver Nightingale + */ + +/** + * A function for splitting a string into tokens ready to be inserted into + * the search index. Uses `lunr.tokenizer.separator` to split strings, change + * the value of this property to change how strings are split into tokens. + * + * This tokenizer will convert its parameter to a string by calling `toString` and + * then will split this string on the character in `lunr.tokenizer.separator`. + * Arrays will have their elements converted to strings and wrapped in a lunr.Token. + * + * Optional metadata can be passed to the tokenizer, this metadata will be cloned and + * added as metadata to every token that is created from the object to be tokenized. + * + * @static + * @param {?(string|object|object[])} obj - The object to convert into tokens + * @param {?object} metadata - Optional metadata to associate with every token + * @returns {lunr.Token[]} + * @see {@link lunr.Pipeline} + */ +lunr.tokenizer = function (obj, metadata) { + if (obj == null || obj == undefined) { + return [] + } + + if (Array.isArray(obj)) { + return obj.map(function (t) { + return new lunr.Token( + lunr.utils.asString(t).toLowerCase(), + lunr.utils.clone(metadata) + ) + }) + } + + var str = obj.toString().toLowerCase(), + len = str.length, + tokens = [] + + for (var sliceEnd = 0, sliceStart = 0; sliceEnd <= len; sliceEnd++) { + var char = str.charAt(sliceEnd), + sliceLength = sliceEnd - sliceStart + + if ((char.match(lunr.tokenizer.separator) || sliceEnd == len)) { + + if (sliceLength > 0) { + var tokenMetadata = lunr.utils.clone(metadata) || {} + tokenMetadata["position"] = [sliceStart, sliceLength] + tokenMetadata["index"] = tokens.length + + tokens.push( + new lunr.Token ( + str.slice(sliceStart, sliceEnd), + tokenMetadata + ) + ) + } + + sliceStart = sliceEnd + 1 + } + + } + + return tokens +} + +/** + * The separator used to split a string into tokens. Override this property to change the behaviour of + * `lunr.tokenizer` behaviour when tokenizing strings. By default this splits on whitespace and hyphens. + * + * @static + * @see lunr.tokenizer + */ +lunr.tokenizer.separator = /[\s\-]+/ +/*! + * lunr.Pipeline + * Copyright (C) 2020 Oliver Nightingale + */ + +/** + * lunr.Pipelines maintain an ordered list of functions to be applied to all + * tokens in documents entering the search index and queries being ran against + * the index. + * + * An instance of lunr.Index created with the lunr shortcut will contain a + * pipeline with a stop word filter and an English language stemmer. Extra + * functions can be added before or after either of these functions or these + * default functions can be removed. + * + * When run the pipeline will call each function in turn, passing a token, the + * index of that token in the original list of all tokens and finally a list of + * all the original tokens. + * + * The output of functions in the pipeline will be passed to the next function + * in the pipeline. To exclude a token from entering the index the function + * should return undefined, the rest of the pipeline will not be called with + * this token. + * + * For serialisation of pipelines to work, all functions used in an instance of + * a pipeline should be registered with lunr.Pipeline. Registered functions can + * then be loaded. If trying to load a serialised pipeline that uses functions + * that are not registered an error will be thrown. + * + * If not planning on serialising the pipeline then registering pipeline functions + * is not necessary. + * + * @constructor + */ +lunr.Pipeline = function () { + this._stack = [] +} + +lunr.Pipeline.registeredFunctions = Object.create(null) + +/** + * A pipeline function maps lunr.Token to lunr.Token. A lunr.Token contains the token + * string as well as all known metadata. A pipeline function can mutate the token string + * or mutate (or add) metadata for a given token. + * + * A pipeline function can indicate that the passed token should be discarded by returning + * null, undefined or an empty string. This token will not be passed to any downstream pipeline + * functions and will not be added to the index. + * + * Multiple tokens can be returned by returning an array of tokens. Each token will be passed + * to any downstream pipeline functions and all will returned tokens will be added to the index. + * + * Any number of pipeline functions may be chained together using a lunr.Pipeline. + * + * @interface lunr.PipelineFunction + * @param {lunr.Token} token - A token from the document being processed. + * @param {number} i - The index of this token in the complete list of tokens for this document/field. + * @param {lunr.Token[]} tokens - All tokens for this document/field. + * @returns {(?lunr.Token|lunr.Token[])} + */ + +/** + * Register a function with the pipeline. + * + * Functions that are used in the pipeline should be registered if the pipeline + * needs to be serialised, or a serialised pipeline needs to be loaded. + * + * Registering a function does not add it to a pipeline, functions must still be + * added to instances of the pipeline for them to be used when running a pipeline. + * + * @param {lunr.PipelineFunction} fn - The function to check for. + * @param {String} label - The label to register this function with + */ +lunr.Pipeline.registerFunction = function (fn, label) { + if (label in this.registeredFunctions) { + lunr.utils.warn('Overwriting existing registered function: ' + label) + } + + fn.label = label + lunr.Pipeline.registeredFunctions[fn.label] = fn +} + +/** + * Warns if the function is not registered as a Pipeline function. + * + * @param {lunr.PipelineFunction} fn - The function to check for. + * @private + */ +lunr.Pipeline.warnIfFunctionNotRegistered = function (fn) { + var isRegistered = fn.label && (fn.label in this.registeredFunctions) + + if (!isRegistered) { + lunr.utils.warn('Function is not registered with pipeline. This may cause problems when serialising the index.\n', fn) + } +} + +/** + * Loads a previously serialised pipeline. + * + * All functions to be loaded must already be registered with lunr.Pipeline. + * If any function from the serialised data has not been registered then an + * error will be thrown. + * + * @param {Object} serialised - The serialised pipeline to load. + * @returns {lunr.Pipeline} + */ +lunr.Pipeline.load = function (serialised) { + var pipeline = new lunr.Pipeline + + serialised.forEach(function (fnName) { + var fn = lunr.Pipeline.registeredFunctions[fnName] + + if (fn) { + pipeline.add(fn) + } else { + throw new Error('Cannot load unregistered function: ' + fnName) + } + }) + + return pipeline +} + +/** + * Adds new functions to the end of the pipeline. + * + * Logs a warning if the function has not been registered. + * + * @param {lunr.PipelineFunction[]} functions - Any number of functions to add to the pipeline. + */ +lunr.Pipeline.prototype.add = function () { + var fns = Array.prototype.slice.call(arguments) + + fns.forEach(function (fn) { + lunr.Pipeline.warnIfFunctionNotRegistered(fn) + this._stack.push(fn) + }, this) +} + +/** + * Adds a single function after a function that already exists in the + * pipeline. + * + * Logs a warning if the function has not been registered. + * + * @param {lunr.PipelineFunction} existingFn - A function that already exists in the pipeline. + * @param {lunr.PipelineFunction} newFn - The new function to add to the pipeline. + */ +lunr.Pipeline.prototype.after = function (existingFn, newFn) { + lunr.Pipeline.warnIfFunctionNotRegistered(newFn) + + var pos = this._stack.indexOf(existingFn) + if (pos == -1) { + throw new Error('Cannot find existingFn') + } + + pos = pos + 1 + this._stack.splice(pos, 0, newFn) +} + +/** + * Adds a single function before a function that already exists in the + * pipeline. + * + * Logs a warning if the function has not been registered. + * + * @param {lunr.PipelineFunction} existingFn - A function that already exists in the pipeline. + * @param {lunr.PipelineFunction} newFn - The new function to add to the pipeline. + */ +lunr.Pipeline.prototype.before = function (existingFn, newFn) { + lunr.Pipeline.warnIfFunctionNotRegistered(newFn) + + var pos = this._stack.indexOf(existingFn) + if (pos == -1) { + throw new Error('Cannot find existingFn') + } + + this._stack.splice(pos, 0, newFn) +} + +/** + * Removes a function from the pipeline. + * + * @param {lunr.PipelineFunction} fn The function to remove from the pipeline. + */ +lunr.Pipeline.prototype.remove = function (fn) { + var pos = this._stack.indexOf(fn) + if (pos == -1) { + return + } + + this._stack.splice(pos, 1) +} + +/** + * Runs the current list of functions that make up the pipeline against the + * passed tokens. + * + * @param {Array} tokens The tokens to run through the pipeline. + * @returns {Array} + */ +lunr.Pipeline.prototype.run = function (tokens) { + var stackLength = this._stack.length + + for (var i = 0; i < stackLength; i++) { + var fn = this._stack[i] + var memo = [] + + for (var j = 0; j < tokens.length; j++) { + var result = fn(tokens[j], j, tokens) + + if (result === null || result === void 0 || result === '') continue + + if (Array.isArray(result)) { + for (var k = 0; k < result.length; k++) { + memo.push(result[k]) + } + } else { + memo.push(result) + } + } + + tokens = memo + } + + return tokens +} + +/** + * Convenience method for passing a string through a pipeline and getting + * strings out. This method takes care of wrapping the passed string in a + * token and mapping the resulting tokens back to strings. + * + * @param {string} str - The string to pass through the pipeline. + * @param {?object} metadata - Optional metadata to associate with the token + * passed to the pipeline. + * @returns {string[]} + */ +lunr.Pipeline.prototype.runString = function (str, metadata) { + var token = new lunr.Token (str, metadata) + + return this.run([token]).map(function (t) { + return t.toString() + }) +} + +/** + * Resets the pipeline by removing any existing processors. + * + */ +lunr.Pipeline.prototype.reset = function () { + this._stack = [] +} + +/** + * Returns a representation of the pipeline ready for serialisation. + * + * Logs a warning if the function has not been registered. + * + * @returns {Array} + */ +lunr.Pipeline.prototype.toJSON = function () { + return this._stack.map(function (fn) { + lunr.Pipeline.warnIfFunctionNotRegistered(fn) + + return fn.label + }) +} +/*! + * lunr.Vector + * Copyright (C) 2020 Oliver Nightingale + */ + +/** + * A vector is used to construct the vector space of documents and queries. These + * vectors support operations to determine the similarity between two documents or + * a document and a query. + * + * Normally no parameters are required for initializing a vector, but in the case of + * loading a previously dumped vector the raw elements can be provided to the constructor. + * + * For performance reasons vectors are implemented with a flat array, where an elements + * index is immediately followed by its value. E.g. [index, value, index, value]. This + * allows the underlying array to be as sparse as possible and still offer decent + * performance when being used for vector calculations. + * + * @constructor + * @param {Number[]} [elements] - The flat list of element index and element value pairs. + */ +lunr.Vector = function (elements) { + this._magnitude = 0 + this.elements = elements || [] +} + + +/** + * Calculates the position within the vector to insert a given index. + * + * This is used internally by insert and upsert. If there are duplicate indexes then + * the position is returned as if the value for that index were to be updated, but it + * is the callers responsibility to check whether there is a duplicate at that index + * + * @param {Number} insertIdx - The index at which the element should be inserted. + * @returns {Number} + */ +lunr.Vector.prototype.positionForIndex = function (index) { + // For an empty vector the tuple can be inserted at the beginning + if (this.elements.length == 0) { + return 0 + } + + var start = 0, + end = this.elements.length / 2, + sliceLength = end - start, + pivotPoint = Math.floor(sliceLength / 2), + pivotIndex = this.elements[pivotPoint * 2] + + while (sliceLength > 1) { + if (pivotIndex < index) { + start = pivotPoint + } + + if (pivotIndex > index) { + end = pivotPoint + } + + if (pivotIndex == index) { + break + } + + sliceLength = end - start + pivotPoint = start + Math.floor(sliceLength / 2) + pivotIndex = this.elements[pivotPoint * 2] + } + + if (pivotIndex == index) { + return pivotPoint * 2 + } + + if (pivotIndex > index) { + return pivotPoint * 2 + } + + if (pivotIndex < index) { + return (pivotPoint + 1) * 2 + } +} + +/** + * Inserts an element at an index within the vector. + * + * Does not allow duplicates, will throw an error if there is already an entry + * for this index. + * + * @param {Number} insertIdx - The index at which the element should be inserted. + * @param {Number} val - The value to be inserted into the vector. + */ +lunr.Vector.prototype.insert = function (insertIdx, val) { + this.upsert(insertIdx, val, function () { + throw "duplicate index" + }) +} + +/** + * Inserts or updates an existing index within the vector. + * + * @param {Number} insertIdx - The index at which the element should be inserted. + * @param {Number} val - The value to be inserted into the vector. + * @param {function} fn - A function that is called for updates, the existing value and the + * requested value are passed as arguments + */ +lunr.Vector.prototype.upsert = function (insertIdx, val, fn) { + this._magnitude = 0 + var position = this.positionForIndex(insertIdx) + + if (this.elements[position] == insertIdx) { + this.elements[position + 1] = fn(this.elements[position + 1], val) + } else { + this.elements.splice(position, 0, insertIdx, val) + } +} + +/** + * Calculates the magnitude of this vector. + * + * @returns {Number} + */ +lunr.Vector.prototype.magnitude = function () { + if (this._magnitude) return this._magnitude + + var sumOfSquares = 0, + elementsLength = this.elements.length + + for (var i = 1; i < elementsLength; i += 2) { + var val = this.elements[i] + sumOfSquares += val * val + } + + return this._magnitude = Math.sqrt(sumOfSquares) +} + +/** + * Calculates the dot product of this vector and another vector. + * + * @param {lunr.Vector} otherVector - The vector to compute the dot product with. + * @returns {Number} + */ +lunr.Vector.prototype.dot = function (otherVector) { + var dotProduct = 0, + a = this.elements, b = otherVector.elements, + aLen = a.length, bLen = b.length, + aVal = 0, bVal = 0, + i = 0, j = 0 + + while (i < aLen && j < bLen) { + aVal = a[i], bVal = b[j] + if (aVal < bVal) { + i += 2 + } else if (aVal > bVal) { + j += 2 + } else if (aVal == bVal) { + dotProduct += a[i + 1] * b[j + 1] + i += 2 + j += 2 + } + } + + return dotProduct +} + +/** + * Calculates the similarity between this vector and another vector. + * + * @param {lunr.Vector} otherVector - The other vector to calculate the + * similarity with. + * @returns {Number} + */ +lunr.Vector.prototype.similarity = function (otherVector) { + return this.dot(otherVector) / this.magnitude() || 0 +} + +/** + * Converts the vector to an array of the elements within the vector. + * + * @returns {Number[]} + */ +lunr.Vector.prototype.toArray = function () { + var output = new Array (this.elements.length / 2) + + for (var i = 1, j = 0; i < this.elements.length; i += 2, j++) { + output[j] = this.elements[i] + } + + return output +} + +/** + * A JSON serializable representation of the vector. + * + * @returns {Number[]} + */ +lunr.Vector.prototype.toJSON = function () { + return this.elements +} +/* eslint-disable */ +/*! + * lunr.stemmer + * Copyright (C) 2020 Oliver Nightingale + * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt + */ + +/** + * lunr.stemmer is an english language stemmer, this is a JavaScript + * implementation of the PorterStemmer taken from http://tartarus.org/~martin + * + * @static + * @implements {lunr.PipelineFunction} + * @param {lunr.Token} token - The string to stem + * @returns {lunr.Token} + * @see {@link lunr.Pipeline} + * @function + */ +lunr.stemmer = (function(){ + var step2list = { + "ational" : "ate", + "tional" : "tion", + "enci" : "ence", + "anci" : "ance", + "izer" : "ize", + "bli" : "ble", + "alli" : "al", + "entli" : "ent", + "eli" : "e", + "ousli" : "ous", + "ization" : "ize", + "ation" : "ate", + "ator" : "ate", + "alism" : "al", + "iveness" : "ive", + "fulness" : "ful", + "ousness" : "ous", + "aliti" : "al", + "iviti" : "ive", + "biliti" : "ble", + "logi" : "log" + }, + + step3list = { + "icate" : "ic", + "ative" : "", + "alize" : "al", + "iciti" : "ic", + "ical" : "ic", + "ful" : "", + "ness" : "" + }, + + c = "[^aeiou]", // consonant + v = "[aeiouy]", // vowel + C = c + "[^aeiouy]*", // consonant sequence + V = v + "[aeiou]*", // vowel sequence + + mgr0 = "^(" + C + ")?" + V + C, // [C]VC... is m>0 + meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$", // [C]VC[V] is m=1 + mgr1 = "^(" + C + ")?" + V + C + V + C, // [C]VCVC... is m>1 + s_v = "^(" + C + ")?" + v; // vowel in stem + + var re_mgr0 = new RegExp(mgr0); + var re_mgr1 = new RegExp(mgr1); + var re_meq1 = new RegExp(meq1); + var re_s_v = new RegExp(s_v); + + var re_1a = /^(.+?)(ss|i)es$/; + var re2_1a = /^(.+?)([^s])s$/; + var re_1b = /^(.+?)eed$/; + var re2_1b = /^(.+?)(ed|ing)$/; + var re_1b_2 = /.$/; + var re2_1b_2 = /(at|bl|iz)$/; + var re3_1b_2 = new RegExp("([^aeiouylsz])\\1$"); + var re4_1b_2 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + + var re_1c = /^(.+?[^aeiou])y$/; + var re_2 = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + + var re_3 = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + + var re_4 = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + var re2_4 = /^(.+?)(s|t)(ion)$/; + + var re_5 = /^(.+?)e$/; + var re_5_1 = /ll$/; + var re3_5 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + + var porterStemmer = function porterStemmer(w) { + var stem, + suffix, + firstch, + re, + re2, + re3, + re4; + + if (w.length < 3) { return w; } + + firstch = w.substr(0,1); + if (firstch == "y") { + w = firstch.toUpperCase() + w.substr(1); + } + + // Step 1a + re = re_1a + re2 = re2_1a; + + if (re.test(w)) { w = w.replace(re,"$1$2"); } + else if (re2.test(w)) { w = w.replace(re2,"$1$2"); } + + // Step 1b + re = re_1b; + re2 = re2_1b; + if (re.test(w)) { + var fp = re.exec(w); + re = re_mgr0; + if (re.test(fp[1])) { + re = re_1b_2; + w = w.replace(re,""); + } + } else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = re_s_v; + if (re2.test(stem)) { + w = stem; + re2 = re2_1b_2; + re3 = re3_1b_2; + re4 = re4_1b_2; + if (re2.test(w)) { w = w + "e"; } + else if (re3.test(w)) { re = re_1b_2; w = w.replace(re,""); } + else if (re4.test(w)) { w = w + "e"; } + } + } + + // Step 1c - replace suffix y or Y by i if preceded by a non-vowel which is not the first letter of the word (so cry -> cri, by -> by, say -> say) + re = re_1c; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + w = stem + "i"; + } + + // Step 2 + re = re_2; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = re_mgr0; + if (re.test(stem)) { + w = stem + step2list[suffix]; + } + } + + // Step 3 + re = re_3; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = re_mgr0; + if (re.test(stem)) { + w = stem + step3list[suffix]; + } + } + + // Step 4 + re = re_4; + re2 = re2_4; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = re_mgr1; + if (re.test(stem)) { + w = stem; + } + } else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = re_mgr1; + if (re2.test(stem)) { + w = stem; + } + } + + // Step 5 + re = re_5; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = re_mgr1; + re2 = re_meq1; + re3 = re3_5; + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) { + w = stem; + } + } + + re = re_5_1; + re2 = re_mgr1; + if (re.test(w) && re2.test(w)) { + re = re_1b_2; + w = w.replace(re,""); + } + + // and turn initial Y back to y + + if (firstch == "y") { + w = firstch.toLowerCase() + w.substr(1); + } + + return w; + }; + + return function (token) { + return token.update(porterStemmer); + } +})(); + +lunr.Pipeline.registerFunction(lunr.stemmer, 'stemmer') +/*! + * lunr.stopWordFilter + * Copyright (C) 2020 Oliver Nightingale + */ + +/** + * lunr.generateStopWordFilter builds a stopWordFilter function from the provided + * list of stop words. + * + * The built in lunr.stopWordFilter is built using this generator and can be used + * to generate custom stopWordFilters for applications or non English languages. + * + * @function + * @param {Array} token The token to pass through the filter + * @returns {lunr.PipelineFunction} + * @see lunr.Pipeline + * @see lunr.stopWordFilter + */ +lunr.generateStopWordFilter = function (stopWords) { + var words = stopWords.reduce(function (memo, stopWord) { + memo[stopWord] = stopWord + return memo + }, {}) + + return function (token) { + if (token && words[token.toString()] !== token.toString()) return token + } +} + +/** + * lunr.stopWordFilter is an English language stop word list filter, any words + * contained in the list will not be passed through the filter. + * + * This is intended to be used in the Pipeline. If the token does not pass the + * filter then undefined will be returned. + * + * @function + * @implements {lunr.PipelineFunction} + * @params {lunr.Token} token - A token to check for being a stop word. + * @returns {lunr.Token} + * @see {@link lunr.Pipeline} + */ +lunr.stopWordFilter = lunr.generateStopWordFilter([ + 'a', + 'able', + 'about', + 'across', + 'after', + 'all', + 'almost', + 'also', + 'am', + 'among', + 'an', + 'and', + 'any', + 'are', + 'as', + 'at', + 'be', + 'because', + 'been', + 'but', + 'by', + 'can', + 'cannot', + 'could', + 'dear', + 'did', + 'do', + 'does', + 'either', + 'else', + 'ever', + 'every', + 'for', + 'from', + 'get', + 'got', + 'had', + 'has', + 'have', + 'he', + 'her', + 'hers', + 'him', + 'his', + 'how', + 'however', + 'i', + 'if', + 'in', + 'into', + 'is', + 'it', + 'its', + 'just', + 'least', + 'let', + 'like', + 'likely', + 'may', + 'me', + 'might', + 'most', + 'must', + 'my', + 'neither', + 'no', + 'nor', + 'not', + 'of', + 'off', + 'often', + 'on', + 'only', + 'or', + 'other', + 'our', + 'own', + 'rather', + 'said', + 'say', + 'says', + 'she', + 'should', + 'since', + 'so', + 'some', + 'than', + 'that', + 'the', + 'their', + 'them', + 'then', + 'there', + 'these', + 'they', + 'this', + 'tis', + 'to', + 'too', + 'twas', + 'us', + 'wants', + 'was', + 'we', + 'were', + 'what', + 'when', + 'where', + 'which', + 'while', + 'who', + 'whom', + 'why', + 'will', + 'with', + 'would', + 'yet', + 'you', + 'your' +]) + +lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'stopWordFilter') +/*! + * lunr.trimmer + * Copyright (C) 2020 Oliver Nightingale + */ + +/** + * lunr.trimmer is a pipeline function for trimming non word + * characters from the beginning and end of tokens before they + * enter the index. + * + * This implementation may not work correctly for non latin + * characters and should either be removed or adapted for use + * with languages with non-latin characters. + * + * @static + * @implements {lunr.PipelineFunction} + * @param {lunr.Token} token The token to pass through the filter + * @returns {lunr.Token} + * @see lunr.Pipeline + */ +lunr.trimmer = function (token) { + return token.update(function (s) { + return s.replace(/^\W+/, '').replace(/\W+$/, '') + }) +} + +lunr.Pipeline.registerFunction(lunr.trimmer, 'trimmer') +/*! + * lunr.TokenSet + * Copyright (C) 2020 Oliver Nightingale + */ + +/** + * A token set is used to store the unique list of all tokens + * within an index. Token sets are also used to represent an + * incoming query to the index, this query token set and index + * token set are then intersected to find which tokens to look + * up in the inverted index. + * + * A token set can hold multiple tokens, as in the case of the + * index token set, or it can hold a single token as in the + * case of a simple query token set. + * + * Additionally token sets are used to perform wildcard matching. + * Leading, contained and trailing wildcards are supported, and + * from this edit distance matching can also be provided. + * + * Token sets are implemented as a minimal finite state automata, + * where both common prefixes and suffixes are shared between tokens. + * This helps to reduce the space used for storing the token set. + * + * @constructor + */ +lunr.TokenSet = function () { + this.final = false + this.edges = {} + this.id = lunr.TokenSet._nextId + lunr.TokenSet._nextId += 1 +} + +/** + * Keeps track of the next, auto increment, identifier to assign + * to a new tokenSet. + * + * TokenSets require a unique identifier to be correctly minimised. + * + * @private + */ +lunr.TokenSet._nextId = 1 + +/** + * Creates a TokenSet instance from the given sorted array of words. + * + * @param {String[]} arr - A sorted array of strings to create the set from. + * @returns {lunr.TokenSet} + * @throws Will throw an error if the input array is not sorted. + */ +lunr.TokenSet.fromArray = function (arr) { + var builder = new lunr.TokenSet.Builder + + for (var i = 0, len = arr.length; i < len; i++) { + builder.insert(arr[i]) + } + + builder.finish() + return builder.root +} + +/** + * Creates a token set from a query clause. + * + * @private + * @param {Object} clause - A single clause from lunr.Query. + * @param {string} clause.term - The query clause term. + * @param {number} [clause.editDistance] - The optional edit distance for the term. + * @returns {lunr.TokenSet} + */ +lunr.TokenSet.fromClause = function (clause) { + if ('editDistance' in clause) { + return lunr.TokenSet.fromFuzzyString(clause.term, clause.editDistance) + } else { + return lunr.TokenSet.fromString(clause.term) + } +} + +/** + * Creates a token set representing a single string with a specified + * edit distance. + * + * Insertions, deletions, substitutions and transpositions are each + * treated as an edit distance of 1. + * + * Increasing the allowed edit distance will have a dramatic impact + * on the performance of both creating and intersecting these TokenSets. + * It is advised to keep the edit distance less than 3. + * + * @param {string} str - The string to create the token set from. + * @param {number} editDistance - The allowed edit distance to match. + * @returns {lunr.Vector} + */ +lunr.TokenSet.fromFuzzyString = function (str, editDistance) { + var root = new lunr.TokenSet + + var stack = [{ + node: root, + editsRemaining: editDistance, + str: str + }] + + while (stack.length) { + var frame = stack.pop() + + // no edit + if (frame.str.length > 0) { + var char = frame.str.charAt(0), + noEditNode + + if (char in frame.node.edges) { + noEditNode = frame.node.edges[char] + } else { + noEditNode = new lunr.TokenSet + frame.node.edges[char] = noEditNode + } + + if (frame.str.length == 1) { + noEditNode.final = true + } + + stack.push({ + node: noEditNode, + editsRemaining: frame.editsRemaining, + str: frame.str.slice(1) + }) + } + + if (frame.editsRemaining == 0) { + continue + } + + // insertion + if ("*" in frame.node.edges) { + var insertionNode = frame.node.edges["*"] + } else { + var insertionNode = new lunr.TokenSet + frame.node.edges["*"] = insertionNode + } + + if (frame.str.length == 0) { + insertionNode.final = true + } + + stack.push({ + node: insertionNode, + editsRemaining: frame.editsRemaining - 1, + str: frame.str + }) + + // deletion + // can only do a deletion if we have enough edits remaining + // and if there are characters left to delete in the string + if (frame.str.length > 1) { + stack.push({ + node: frame.node, + editsRemaining: frame.editsRemaining - 1, + str: frame.str.slice(1) + }) + } + + // deletion + // just removing the last character from the str + if (frame.str.length == 1) { + frame.node.final = true + } + + // substitution + // can only do a substitution if we have enough edits remaining + // and if there are characters left to substitute + if (frame.str.length >= 1) { + if ("*" in frame.node.edges) { + var substitutionNode = frame.node.edges["*"] + } else { + var substitutionNode = new lunr.TokenSet + frame.node.edges["*"] = substitutionNode + } + + if (frame.str.length == 1) { + substitutionNode.final = true + } + + stack.push({ + node: substitutionNode, + editsRemaining: frame.editsRemaining - 1, + str: frame.str.slice(1) + }) + } + + // transposition + // can only do a transposition if there are edits remaining + // and there are enough characters to transpose + if (frame.str.length > 1) { + var charA = frame.str.charAt(0), + charB = frame.str.charAt(1), + transposeNode + + if (charB in frame.node.edges) { + transposeNode = frame.node.edges[charB] + } else { + transposeNode = new lunr.TokenSet + frame.node.edges[charB] = transposeNode + } + + if (frame.str.length == 1) { + transposeNode.final = true + } + + stack.push({ + node: transposeNode, + editsRemaining: frame.editsRemaining - 1, + str: charA + frame.str.slice(2) + }) + } + } + + return root +} + +/** + * Creates a TokenSet from a string. + * + * The string may contain one or more wildcard characters (*) + * that will allow wildcard matching when intersecting with + * another TokenSet. + * + * @param {string} str - The string to create a TokenSet from. + * @returns {lunr.TokenSet} + */ +lunr.TokenSet.fromString = function (str) { + var node = new lunr.TokenSet, + root = node + + /* + * Iterates through all characters within the passed string + * appending a node for each character. + * + * When a wildcard character is found then a self + * referencing edge is introduced to continually match + * any number of any characters. + */ + for (var i = 0, len = str.length; i < len; i++) { + var char = str[i], + final = (i == len - 1) + + if (char == "*") { + node.edges[char] = node + node.final = final + + } else { + var next = new lunr.TokenSet + next.final = final + + node.edges[char] = next + node = next + } + } + + return root +} + +/** + * Converts this TokenSet into an array of strings + * contained within the TokenSet. + * + * This is not intended to be used on a TokenSet that + * contains wildcards, in these cases the results are + * undefined and are likely to cause an infinite loop. + * + * @returns {string[]} + */ +lunr.TokenSet.prototype.toArray = function () { + var words = [] + + var stack = [{ + prefix: "", + node: this + }] + + while (stack.length) { + var frame = stack.pop(), + edges = Object.keys(frame.node.edges), + len = edges.length + + if (frame.node.final) { + /* In Safari, at this point the prefix is sometimes corrupted, see: + * https://github.com/olivernn/lunr.js/issues/279 Calling any + * String.prototype method forces Safari to "cast" this string to what + * it's supposed to be, fixing the bug. */ + frame.prefix.charAt(0) + words.push(frame.prefix) + } + + for (var i = 0; i < len; i++) { + var edge = edges[i] + + stack.push({ + prefix: frame.prefix.concat(edge), + node: frame.node.edges[edge] + }) + } + } + + return words +} + +/** + * Generates a string representation of a TokenSet. + * + * This is intended to allow TokenSets to be used as keys + * in objects, largely to aid the construction and minimisation + * of a TokenSet. As such it is not designed to be a human + * friendly representation of the TokenSet. + * + * @returns {string} + */ +lunr.TokenSet.prototype.toString = function () { + // NOTE: Using Object.keys here as this.edges is very likely + // to enter 'hash-mode' with many keys being added + // + // avoiding a for-in loop here as it leads to the function + // being de-optimised (at least in V8). From some simple + // benchmarks the performance is comparable, but allowing + // V8 to optimize may mean easy performance wins in the future. + + if (this._str) { + return this._str + } + + var str = this.final ? '1' : '0', + labels = Object.keys(this.edges).sort(), + len = labels.length + + for (var i = 0; i < len; i++) { + var label = labels[i], + node = this.edges[label] + + str = str + label + node.id + } + + return str +} + +/** + * Returns a new TokenSet that is the intersection of + * this TokenSet and the passed TokenSet. + * + * This intersection will take into account any wildcards + * contained within the TokenSet. + * + * @param {lunr.TokenSet} b - An other TokenSet to intersect with. + * @returns {lunr.TokenSet} + */ +lunr.TokenSet.prototype.intersect = function (b) { + var output = new lunr.TokenSet, + frame = undefined + + var stack = [{ + qNode: b, + output: output, + node: this + }] + + while (stack.length) { + frame = stack.pop() + + // NOTE: As with the #toString method, we are using + // Object.keys and a for loop instead of a for-in loop + // as both of these objects enter 'hash' mode, causing + // the function to be de-optimised in V8 + var qEdges = Object.keys(frame.qNode.edges), + qLen = qEdges.length, + nEdges = Object.keys(frame.node.edges), + nLen = nEdges.length + + for (var q = 0; q < qLen; q++) { + var qEdge = qEdges[q] + + for (var n = 0; n < nLen; n++) { + var nEdge = nEdges[n] + + if (nEdge == qEdge || qEdge == '*') { + var node = frame.node.edges[nEdge], + qNode = frame.qNode.edges[qEdge], + final = node.final && qNode.final, + next = undefined + + if (nEdge in frame.output.edges) { + // an edge already exists for this character + // no need to create a new node, just set the finality + // bit unless this node is already final + next = frame.output.edges[nEdge] + next.final = next.final || final + + } else { + // no edge exists yet, must create one + // set the finality bit and insert it + // into the output + next = new lunr.TokenSet + next.final = final + frame.output.edges[nEdge] = next + } + + stack.push({ + qNode: qNode, + output: next, + node: node + }) + } + } + } + } + + return output +} +lunr.TokenSet.Builder = function () { + this.previousWord = "" + this.root = new lunr.TokenSet + this.uncheckedNodes = [] + this.minimizedNodes = {} +} + +lunr.TokenSet.Builder.prototype.insert = function (word) { + var node, + commonPrefix = 0 + + if (word < this.previousWord) { + throw new Error ("Out of order word insertion") + } + + for (var i = 0; i < word.length && i < this.previousWord.length; i++) { + if (word[i] != this.previousWord[i]) break + commonPrefix++ + } + + this.minimize(commonPrefix) + + if (this.uncheckedNodes.length == 0) { + node = this.root + } else { + node = this.uncheckedNodes[this.uncheckedNodes.length - 1].child + } + + for (var i = commonPrefix; i < word.length; i++) { + var nextNode = new lunr.TokenSet, + char = word[i] + + node.edges[char] = nextNode + + this.uncheckedNodes.push({ + parent: node, + char: char, + child: nextNode + }) + + node = nextNode + } + + node.final = true + this.previousWord = word +} + +lunr.TokenSet.Builder.prototype.finish = function () { + this.minimize(0) +} + +lunr.TokenSet.Builder.prototype.minimize = function (downTo) { + for (var i = this.uncheckedNodes.length - 1; i >= downTo; i--) { + var node = this.uncheckedNodes[i], + childKey = node.child.toString() + + if (childKey in this.minimizedNodes) { + node.parent.edges[node.char] = this.minimizedNodes[childKey] + } else { + // Cache the key for this node since + // we know it can't change anymore + node.child._str = childKey + + this.minimizedNodes[childKey] = node.child + } + + this.uncheckedNodes.pop() + } +} +/*! + * lunr.Index + * Copyright (C) 2020 Oliver Nightingale + */ + +/** + * An index contains the built index of all documents and provides a query interface + * to the index. + * + * Usually instances of lunr.Index will not be created using this constructor, instead + * lunr.Builder should be used to construct new indexes, or lunr.Index.load should be + * used to load previously built and serialized indexes. + * + * @constructor + * @param {Object} attrs - The attributes of the built search index. + * @param {Object} attrs.invertedIndex - An index of term/field to document reference. + * @param {Object} attrs.fieldVectors - Field vectors + * @param {lunr.TokenSet} attrs.tokenSet - An set of all corpus tokens. + * @param {string[]} attrs.fields - The names of indexed document fields. + * @param {lunr.Pipeline} attrs.pipeline - The pipeline to use for search terms. + */ +lunr.Index = function (attrs) { + this.invertedIndex = attrs.invertedIndex + this.fieldVectors = attrs.fieldVectors + this.tokenSet = attrs.tokenSet + this.fields = attrs.fields + this.pipeline = attrs.pipeline +} + +/** + * A result contains details of a document matching a search query. + * @typedef {Object} lunr.Index~Result + * @property {string} ref - The reference of the document this result represents. + * @property {number} score - A number between 0 and 1 representing how similar this document is to the query. + * @property {lunr.MatchData} matchData - Contains metadata about this match including which term(s) caused the match. + */ + +/** + * Although lunr provides the ability to create queries using lunr.Query, it also provides a simple + * query language which itself is parsed into an instance of lunr.Query. + * + * For programmatically building queries it is advised to directly use lunr.Query, the query language + * is best used for human entered text rather than program generated text. + * + * At its simplest queries can just be a single term, e.g. `hello`, multiple terms are also supported + * and will be combined with OR, e.g `hello world` will match documents that contain either 'hello' + * or 'world', though those that contain both will rank higher in the results. + * + * Wildcards can be included in terms to match one or more unspecified characters, these wildcards can + * be inserted anywhere within the term, and more than one wildcard can exist in a single term. Adding + * wildcards will increase the number of documents that will be found but can also have a negative + * impact on query performance, especially with wildcards at the beginning of a term. + * + * Terms can be restricted to specific fields, e.g. `title:hello`, only documents with the term + * hello in the title field will match this query. Using a field not present in the index will lead + * to an error being thrown. + * + * Modifiers can also be added to terms, lunr supports edit distance and boost modifiers on terms. A term + * boost will make documents matching that term score higher, e.g. `foo^5`. Edit distance is also supported + * to provide fuzzy matching, e.g. 'hello~2' will match documents with hello with an edit distance of 2. + * Avoid large values for edit distance to improve query performance. + * + * Each term also supports a presence modifier. By default a term's presence in document is optional, however + * this can be changed to either required or prohibited. For a term's presence to be required in a document the + * term should be prefixed with a '+', e.g. `+foo bar` is a search for documents that must contain 'foo' and + * optionally contain 'bar'. Conversely a leading '-' sets the terms presence to prohibited, i.e. it must not + * appear in a document, e.g. `-foo bar` is a search for documents that do not contain 'foo' but may contain 'bar'. + * + * To escape special characters the backslash character '\' can be used, this allows searches to include + * characters that would normally be considered modifiers, e.g. `foo\~2` will search for a term "foo~2" instead + * of attempting to apply a boost of 2 to the search term "foo". + * + * @typedef {string} lunr.Index~QueryString + * @example Simple single term query + * hello + * @example Multiple term query + * hello world + * @example term scoped to a field + * title:hello + * @example term with a boost of 10 + * hello^10 + * @example term with an edit distance of 2 + * hello~2 + * @example terms with presence modifiers + * -foo +bar baz + */ + +/** + * Performs a search against the index using lunr query syntax. + * + * Results will be returned sorted by their score, the most relevant results + * will be returned first. For details on how the score is calculated, please see + * the {@link https://lunrjs.com/guides/searching.html#scoring|guide}. + * + * For more programmatic querying use lunr.Index#query. + * + * @param {lunr.Index~QueryString} queryString - A string containing a lunr query. + * @throws {lunr.QueryParseError} If the passed query string cannot be parsed. + * @returns {lunr.Index~Result[]} + */ +lunr.Index.prototype.search = function (queryString) { + return this.query(function (query) { + var parser = new lunr.QueryParser(queryString, query) + parser.parse() + }) +} + +/** + * A query builder callback provides a query object to be used to express + * the query to perform on the index. + * + * @callback lunr.Index~queryBuilder + * @param {lunr.Query} query - The query object to build up. + * @this lunr.Query + */ + +/** + * Performs a query against the index using the yielded lunr.Query object. + * + * If performing programmatic queries against the index, this method is preferred + * over lunr.Index#search so as to avoid the additional query parsing overhead. + * + * A query object is yielded to the supplied function which should be used to + * express the query to be run against the index. + * + * Note that although this function takes a callback parameter it is _not_ an + * asynchronous operation, the callback is just yielded a query object to be + * customized. + * + * @param {lunr.Index~queryBuilder} fn - A function that is used to build the query. + * @returns {lunr.Index~Result[]} + */ +lunr.Index.prototype.query = function (fn) { + // for each query clause + // * process terms + // * expand terms from token set + // * find matching documents and metadata + // * get document vectors + // * score documents + + var query = new lunr.Query(this.fields), + matchingFields = Object.create(null), + queryVectors = Object.create(null), + termFieldCache = Object.create(null), + requiredMatches = Object.create(null), + prohibitedMatches = Object.create(null) + + /* + * To support field level boosts a query vector is created per + * field. An empty vector is eagerly created to support negated + * queries. + */ + for (var i = 0; i < this.fields.length; i++) { + queryVectors[this.fields[i]] = new lunr.Vector + } + + fn.call(query, query) + + for (var i = 0; i < query.clauses.length; i++) { + /* + * Unless the pipeline has been disabled for this term, which is + * the case for terms with wildcards, we need to pass the clause + * term through the search pipeline. A pipeline returns an array + * of processed terms. Pipeline functions may expand the passed + * term, which means we may end up performing multiple index lookups + * for a single query term. + */ + var clause = query.clauses[i], + terms = null, + clauseMatches = lunr.Set.empty + + if (clause.usePipeline) { + terms = this.pipeline.runString(clause.term, { + fields: clause.fields + }) + } else { + terms = [clause.term] + } + + for (var m = 0; m < terms.length; m++) { + var term = terms[m] + + /* + * Each term returned from the pipeline needs to use the same query + * clause object, e.g. the same boost and or edit distance. The + * simplest way to do this is to re-use the clause object but mutate + * its term property. + */ + clause.term = term + + /* + * From the term in the clause we create a token set which will then + * be used to intersect the indexes token set to get a list of terms + * to lookup in the inverted index + */ + var termTokenSet = lunr.TokenSet.fromClause(clause), + expandedTerms = this.tokenSet.intersect(termTokenSet).toArray() + + /* + * If a term marked as required does not exist in the tokenSet it is + * impossible for the search to return any matches. We set all the field + * scoped required matches set to empty and stop examining any further + * clauses. + */ + if (expandedTerms.length === 0 && clause.presence === lunr.Query.presence.REQUIRED) { + for (var k = 0; k < clause.fields.length; k++) { + var field = clause.fields[k] + requiredMatches[field] = lunr.Set.empty + } + + break + } + + for (var j = 0; j < expandedTerms.length; j++) { + /* + * For each term get the posting and termIndex, this is required for + * building the query vector. + */ + var expandedTerm = expandedTerms[j], + posting = this.invertedIndex[expandedTerm], + termIndex = posting._index + + for (var k = 0; k < clause.fields.length; k++) { + /* + * For each field that this query term is scoped by (by default + * all fields are in scope) we need to get all the document refs + * that have this term in that field. + * + * The posting is the entry in the invertedIndex for the matching + * term from above. + */ + var field = clause.fields[k], + fieldPosting = posting[field], + matchingDocumentRefs = Object.keys(fieldPosting), + termField = expandedTerm + "/" + field, + matchingDocumentsSet = new lunr.Set(matchingDocumentRefs) + + /* + * if the presence of this term is required ensure that the matching + * documents are added to the set of required matches for this clause. + * + */ + if (clause.presence == lunr.Query.presence.REQUIRED) { + clauseMatches = clauseMatches.union(matchingDocumentsSet) + + if (requiredMatches[field] === undefined) { + requiredMatches[field] = lunr.Set.complete + } + } + + /* + * if the presence of this term is prohibited ensure that the matching + * documents are added to the set of prohibited matches for this field, + * creating that set if it does not yet exist. + */ + if (clause.presence == lunr.Query.presence.PROHIBITED) { + if (prohibitedMatches[field] === undefined) { + prohibitedMatches[field] = lunr.Set.empty + } + + prohibitedMatches[field] = prohibitedMatches[field].union(matchingDocumentsSet) + + /* + * Prohibited matches should not be part of the query vector used for + * similarity scoring and no metadata should be extracted so we continue + * to the next field + */ + continue + } + + /* + * The query field vector is populated using the termIndex found for + * the term and a unit value with the appropriate boost applied. + * Using upsert because there could already be an entry in the vector + * for the term we are working with. In that case we just add the scores + * together. + */ + queryVectors[field].upsert(termIndex, clause.boost, function (a, b) { return a + b }) + + /** + * If we've already seen this term, field combo then we've already collected + * the matching documents and metadata, no need to go through all that again + */ + if (termFieldCache[termField]) { + continue + } + + for (var l = 0; l < matchingDocumentRefs.length; l++) { + /* + * All metadata for this term/field/document triple + * are then extracted and collected into an instance + * of lunr.MatchData ready to be returned in the query + * results + */ + var matchingDocumentRef = matchingDocumentRefs[l], + matchingFieldRef = new lunr.FieldRef (matchingDocumentRef, field), + metadata = fieldPosting[matchingDocumentRef], + fieldMatch + + if ((fieldMatch = matchingFields[matchingFieldRef]) === undefined) { + matchingFields[matchingFieldRef] = new lunr.MatchData (expandedTerm, field, metadata) + } else { + fieldMatch.add(expandedTerm, field, metadata) + } + + } + + termFieldCache[termField] = true + } + } + } + + /** + * If the presence was required we need to update the requiredMatches field sets. + * We do this after all fields for the term have collected their matches because + * the clause terms presence is required in _any_ of the fields not _all_ of the + * fields. + */ + if (clause.presence === lunr.Query.presence.REQUIRED) { + for (var k = 0; k < clause.fields.length; k++) { + var field = clause.fields[k] + requiredMatches[field] = requiredMatches[field].intersect(clauseMatches) + } + } + } + + /** + * Need to combine the field scoped required and prohibited + * matching documents into a global set of required and prohibited + * matches + */ + var allRequiredMatches = lunr.Set.complete, + allProhibitedMatches = lunr.Set.empty + + for (var i = 0; i < this.fields.length; i++) { + var field = this.fields[i] + + if (requiredMatches[field]) { + allRequiredMatches = allRequiredMatches.intersect(requiredMatches[field]) + } + + if (prohibitedMatches[field]) { + allProhibitedMatches = allProhibitedMatches.union(prohibitedMatches[field]) + } + } + + var matchingFieldRefs = Object.keys(matchingFields), + results = [], + matches = Object.create(null) + + /* + * If the query is negated (contains only prohibited terms) + * we need to get _all_ fieldRefs currently existing in the + * index. This is only done when we know that the query is + * entirely prohibited terms to avoid any cost of getting all + * fieldRefs unnecessarily. + * + * Additionally, blank MatchData must be created to correctly + * populate the results. + */ + if (query.isNegated()) { + matchingFieldRefs = Object.keys(this.fieldVectors) + + for (var i = 0; i < matchingFieldRefs.length; i++) { + var matchingFieldRef = matchingFieldRefs[i] + var fieldRef = lunr.FieldRef.fromString(matchingFieldRef) + matchingFields[matchingFieldRef] = new lunr.MatchData + } + } + + for (var i = 0; i < matchingFieldRefs.length; i++) { + /* + * Currently we have document fields that match the query, but we + * need to return documents. The matchData and scores are combined + * from multiple fields belonging to the same document. + * + * Scores are calculated by field, using the query vectors created + * above, and combined into a final document score using addition. + */ + var fieldRef = lunr.FieldRef.fromString(matchingFieldRefs[i]), + docRef = fieldRef.docRef + + if (!allRequiredMatches.contains(docRef)) { + continue + } + + if (allProhibitedMatches.contains(docRef)) { + continue + } + + var fieldVector = this.fieldVectors[fieldRef], + score = queryVectors[fieldRef.fieldName].similarity(fieldVector), + docMatch + + if ((docMatch = matches[docRef]) !== undefined) { + docMatch.score += score + docMatch.matchData.combine(matchingFields[fieldRef]) + } else { + var match = { + ref: docRef, + score: score, + matchData: matchingFields[fieldRef] + } + matches[docRef] = match + results.push(match) + } + } + + /* + * Sort the results objects by score, highest first. + */ + return results.sort(function (a, b) { + return b.score - a.score + }) +} + +/** + * Prepares the index for JSON serialization. + * + * The schema for this JSON blob will be described in a + * separate JSON schema file. + * + * @returns {Object} + */ +lunr.Index.prototype.toJSON = function () { + var invertedIndex = Object.keys(this.invertedIndex) + .sort() + .map(function (term) { + return [term, this.invertedIndex[term]] + }, this) + + var fieldVectors = Object.keys(this.fieldVectors) + .map(function (ref) { + return [ref, this.fieldVectors[ref].toJSON()] + }, this) + + return { + version: lunr.version, + fields: this.fields, + fieldVectors: fieldVectors, + invertedIndex: invertedIndex, + pipeline: this.pipeline.toJSON() + } +} + +/** + * Loads a previously serialized lunr.Index + * + * @param {Object} serializedIndex - A previously serialized lunr.Index + * @returns {lunr.Index} + */ +lunr.Index.load = function (serializedIndex) { + var attrs = {}, + fieldVectors = {}, + serializedVectors = serializedIndex.fieldVectors, + invertedIndex = Object.create(null), + serializedInvertedIndex = serializedIndex.invertedIndex, + tokenSetBuilder = new lunr.TokenSet.Builder, + pipeline = lunr.Pipeline.load(serializedIndex.pipeline) + + if (serializedIndex.version != lunr.version) { + lunr.utils.warn("Version mismatch when loading serialised index. Current version of lunr '" + lunr.version + "' does not match serialized index '" + serializedIndex.version + "'") + } + + for (var i = 0; i < serializedVectors.length; i++) { + var tuple = serializedVectors[i], + ref = tuple[0], + elements = tuple[1] + + fieldVectors[ref] = new lunr.Vector(elements) + } + + for (var i = 0; i < serializedInvertedIndex.length; i++) { + var tuple = serializedInvertedIndex[i], + term = tuple[0], + posting = tuple[1] + + tokenSetBuilder.insert(term) + invertedIndex[term] = posting + } + + tokenSetBuilder.finish() + + attrs.fields = serializedIndex.fields + + attrs.fieldVectors = fieldVectors + attrs.invertedIndex = invertedIndex + attrs.tokenSet = tokenSetBuilder.root + attrs.pipeline = pipeline + + return new lunr.Index(attrs) +} +/*! + * lunr.Builder + * Copyright (C) 2020 Oliver Nightingale + */ + +/** + * lunr.Builder performs indexing on a set of documents and + * returns instances of lunr.Index ready for querying. + * + * All configuration of the index is done via the builder, the + * fields to index, the document reference, the text processing + * pipeline and document scoring parameters are all set on the + * builder before indexing. + * + * @constructor + * @property {string} _ref - Internal reference to the document reference field. + * @property {string[]} _fields - Internal reference to the document fields to index. + * @property {object} invertedIndex - The inverted index maps terms to document fields. + * @property {object} documentTermFrequencies - Keeps track of document term frequencies. + * @property {object} documentLengths - Keeps track of the length of documents added to the index. + * @property {lunr.tokenizer} tokenizer - Function for splitting strings into tokens for indexing. + * @property {lunr.Pipeline} pipeline - The pipeline performs text processing on tokens before indexing. + * @property {lunr.Pipeline} searchPipeline - A pipeline for processing search terms before querying the index. + * @property {number} documentCount - Keeps track of the total number of documents indexed. + * @property {number} _b - A parameter to control field length normalization, setting this to 0 disabled normalization, 1 fully normalizes field lengths, the default value is 0.75. + * @property {number} _k1 - A parameter to control how quickly an increase in term frequency results in term frequency saturation, the default value is 1.2. + * @property {number} termIndex - A counter incremented for each unique term, used to identify a terms position in the vector space. + * @property {array} metadataWhitelist - A list of metadata keys that have been whitelisted for entry in the index. + */ +lunr.Builder = function () { + this._ref = "id" + this._fields = Object.create(null) + this._documents = Object.create(null) + this.invertedIndex = Object.create(null) + this.fieldTermFrequencies = {} + this.fieldLengths = {} + this.tokenizer = lunr.tokenizer + this.pipeline = new lunr.Pipeline + this.searchPipeline = new lunr.Pipeline + this.documentCount = 0 + this._b = 0.75 + this._k1 = 1.2 + this.termIndex = 0 + this.metadataWhitelist = [] +} + +/** + * Sets the document field used as the document reference. Every document must have this field. + * The type of this field in the document should be a string, if it is not a string it will be + * coerced into a string by calling toString. + * + * The default ref is 'id'. + * + * The ref should _not_ be changed during indexing, it should be set before any documents are + * added to the index. Changing it during indexing can lead to inconsistent results. + * + * @param {string} ref - The name of the reference field in the document. + */ +lunr.Builder.prototype.ref = function (ref) { + this._ref = ref +} + +/** + * A function that is used to extract a field from a document. + * + * Lunr expects a field to be at the top level of a document, if however the field + * is deeply nested within a document an extractor function can be used to extract + * the right field for indexing. + * + * @callback fieldExtractor + * @param {object} doc - The document being added to the index. + * @returns {?(string|object|object[])} obj - The object that will be indexed for this field. + * @example Extracting a nested field + * function (doc) { return doc.nested.field } + */ + +/** + * Adds a field to the list of document fields that will be indexed. Every document being + * indexed should have this field. Null values for this field in indexed documents will + * not cause errors but will limit the chance of that document being retrieved by searches. + * + * All fields should be added before adding documents to the index. Adding fields after + * a document has been indexed will have no effect on already indexed documents. + * + * Fields can be boosted at build time. This allows terms within that field to have more + * importance when ranking search results. Use a field boost to specify that matches within + * one field are more important than other fields. + * + * @param {string} fieldName - The name of a field to index in all documents. + * @param {object} attributes - Optional attributes associated with this field. + * @param {number} [attributes.boost=1] - Boost applied to all terms within this field. + * @param {fieldExtractor} [attributes.extractor] - Function to extract a field from a document. + * @throws {RangeError} fieldName cannot contain unsupported characters '/' + */ +lunr.Builder.prototype.field = function (fieldName, attributes) { + if (/\//.test(fieldName)) { + throw new RangeError ("Field '" + fieldName + "' contains illegal character '/'") + } + + this._fields[fieldName] = attributes || {} +} + +/** + * A parameter to tune the amount of field length normalisation that is applied when + * calculating relevance scores. A value of 0 will completely disable any normalisation + * and a value of 1 will fully normalise field lengths. The default is 0.75. Values of b + * will be clamped to the range 0 - 1. + * + * @param {number} number - The value to set for this tuning parameter. + */ +lunr.Builder.prototype.b = function (number) { + if (number < 0) { + this._b = 0 + } else if (number > 1) { + this._b = 1 + } else { + this._b = number + } +} + +/** + * A parameter that controls the speed at which a rise in term frequency results in term + * frequency saturation. The default value is 1.2. Setting this to a higher value will give + * slower saturation levels, a lower value will result in quicker saturation. + * + * @param {number} number - The value to set for this tuning parameter. + */ +lunr.Builder.prototype.k1 = function (number) { + this._k1 = number +} + +/** + * Adds a document to the index. + * + * Before adding fields to the index the index should have been fully setup, with the document + * ref and all fields to index already having been specified. + * + * The document must have a field name as specified by the ref (by default this is 'id') and + * it should have all fields defined for indexing, though null or undefined values will not + * cause errors. + * + * Entire documents can be boosted at build time. Applying a boost to a document indicates that + * this document should rank higher in search results than other documents. + * + * @param {object} doc - The document to add to the index. + * @param {object} attributes - Optional attributes associated with this document. + * @param {number} [attributes.boost=1] - Boost applied to all terms within this document. + */ +lunr.Builder.prototype.add = function (doc, attributes) { + var docRef = doc[this._ref], + fields = Object.keys(this._fields) + + this._documents[docRef] = attributes || {} + this.documentCount += 1 + + for (var i = 0; i < fields.length; i++) { + var fieldName = fields[i], + extractor = this._fields[fieldName].extractor, + field = extractor ? extractor(doc) : doc[fieldName], + tokens = this.tokenizer(field, { + fields: [fieldName] + }), + terms = this.pipeline.run(tokens), + fieldRef = new lunr.FieldRef (docRef, fieldName), + fieldTerms = Object.create(null) + + this.fieldTermFrequencies[fieldRef] = fieldTerms + this.fieldLengths[fieldRef] = 0 + + // store the length of this field for this document + this.fieldLengths[fieldRef] += terms.length + + // calculate term frequencies for this field + for (var j = 0; j < terms.length; j++) { + var term = terms[j] + + if (fieldTerms[term] == undefined) { + fieldTerms[term] = 0 + } + + fieldTerms[term] += 1 + + // add to inverted index + // create an initial posting if one doesn't exist + if (this.invertedIndex[term] == undefined) { + var posting = Object.create(null) + posting["_index"] = this.termIndex + this.termIndex += 1 + + for (var k = 0; k < fields.length; k++) { + posting[fields[k]] = Object.create(null) + } + + this.invertedIndex[term] = posting + } + + // add an entry for this term/fieldName/docRef to the invertedIndex + if (this.invertedIndex[term][fieldName][docRef] == undefined) { + this.invertedIndex[term][fieldName][docRef] = Object.create(null) + } + + // store all whitelisted metadata about this token in the + // inverted index + for (var l = 0; l < this.metadataWhitelist.length; l++) { + var metadataKey = this.metadataWhitelist[l], + metadata = term.metadata[metadataKey] + + if (this.invertedIndex[term][fieldName][docRef][metadataKey] == undefined) { + this.invertedIndex[term][fieldName][docRef][metadataKey] = [] + } + + this.invertedIndex[term][fieldName][docRef][metadataKey].push(metadata) + } + } + + } +} + +/** + * Calculates the average document length for this index + * + * @private + */ +lunr.Builder.prototype.calculateAverageFieldLengths = function () { + + var fieldRefs = Object.keys(this.fieldLengths), + numberOfFields = fieldRefs.length, + accumulator = {}, + documentsWithField = {} + + for (var i = 0; i < numberOfFields; i++) { + var fieldRef = lunr.FieldRef.fromString(fieldRefs[i]), + field = fieldRef.fieldName + + documentsWithField[field] || (documentsWithField[field] = 0) + documentsWithField[field] += 1 + + accumulator[field] || (accumulator[field] = 0) + accumulator[field] += this.fieldLengths[fieldRef] + } + + var fields = Object.keys(this._fields) + + for (var i = 0; i < fields.length; i++) { + var fieldName = fields[i] + accumulator[fieldName] = accumulator[fieldName] / documentsWithField[fieldName] + } + + this.averageFieldLength = accumulator +} + +/** + * Builds a vector space model of every document using lunr.Vector + * + * @private + */ +lunr.Builder.prototype.createFieldVectors = function () { + var fieldVectors = {}, + fieldRefs = Object.keys(this.fieldTermFrequencies), + fieldRefsLength = fieldRefs.length, + termIdfCache = Object.create(null) + + for (var i = 0; i < fieldRefsLength; i++) { + var fieldRef = lunr.FieldRef.fromString(fieldRefs[i]), + fieldName = fieldRef.fieldName, + fieldLength = this.fieldLengths[fieldRef], + fieldVector = new lunr.Vector, + termFrequencies = this.fieldTermFrequencies[fieldRef], + terms = Object.keys(termFrequencies), + termsLength = terms.length + + + var fieldBoost = this._fields[fieldName].boost || 1, + docBoost = this._documents[fieldRef.docRef].boost || 1 + + for (var j = 0; j < termsLength; j++) { + var term = terms[j], + tf = termFrequencies[term], + termIndex = this.invertedIndex[term]._index, + idf, score, scoreWithPrecision + + if (termIdfCache[term] === undefined) { + idf = lunr.idf(this.invertedIndex[term], this.documentCount) + termIdfCache[term] = idf + } else { + idf = termIdfCache[term] + } + + score = idf * ((this._k1 + 1) * tf) / (this._k1 * (1 - this._b + this._b * (fieldLength / this.averageFieldLength[fieldName])) + tf) + score *= fieldBoost + score *= docBoost + scoreWithPrecision = Math.round(score * 1000) / 1000 + // Converts 1.23456789 to 1.234. + // Reducing the precision so that the vectors take up less + // space when serialised. Doing it now so that they behave + // the same before and after serialisation. Also, this is + // the fastest approach to reducing a number's precision in + // JavaScript. + + fieldVector.insert(termIndex, scoreWithPrecision) + } + + fieldVectors[fieldRef] = fieldVector + } + + this.fieldVectors = fieldVectors +} + +/** + * Creates a token set of all tokens in the index using lunr.TokenSet + * + * @private + */ +lunr.Builder.prototype.createTokenSet = function () { + this.tokenSet = lunr.TokenSet.fromArray( + Object.keys(this.invertedIndex).sort() + ) +} + +/** + * Builds the index, creating an instance of lunr.Index. + * + * This completes the indexing process and should only be called + * once all documents have been added to the index. + * + * @returns {lunr.Index} + */ +lunr.Builder.prototype.build = function () { + this.calculateAverageFieldLengths() + this.createFieldVectors() + this.createTokenSet() + + return new lunr.Index({ + invertedIndex: this.invertedIndex, + fieldVectors: this.fieldVectors, + tokenSet: this.tokenSet, + fields: Object.keys(this._fields), + pipeline: this.searchPipeline + }) +} + +/** + * Applies a plugin to the index builder. + * + * A plugin is a function that is called with the index builder as its context. + * Plugins can be used to customise or extend the behaviour of the index + * in some way. A plugin is just a function, that encapsulated the custom + * behaviour that should be applied when building the index. + * + * The plugin function will be called with the index builder as its argument, additional + * arguments can also be passed when calling use. The function will be called + * with the index builder as its context. + * + * @param {Function} plugin The plugin to apply. + */ +lunr.Builder.prototype.use = function (fn) { + var args = Array.prototype.slice.call(arguments, 1) + args.unshift(this) + fn.apply(this, args) +} +/** + * Contains and collects metadata about a matching document. + * A single instance of lunr.MatchData is returned as part of every + * lunr.Index~Result. + * + * @constructor + * @param {string} term - The term this match data is associated with + * @param {string} field - The field in which the term was found + * @param {object} metadata - The metadata recorded about this term in this field + * @property {object} metadata - A cloned collection of metadata associated with this document. + * @see {@link lunr.Index~Result} + */ +lunr.MatchData = function (term, field, metadata) { + var clonedMetadata = Object.create(null), + metadataKeys = Object.keys(metadata || {}) + + // Cloning the metadata to prevent the original + // being mutated during match data combination. + // Metadata is kept in an array within the inverted + // index so cloning the data can be done with + // Array#slice + for (var i = 0; i < metadataKeys.length; i++) { + var key = metadataKeys[i] + clonedMetadata[key] = metadata[key].slice() + } + + this.metadata = Object.create(null) + + if (term !== undefined) { + this.metadata[term] = Object.create(null) + this.metadata[term][field] = clonedMetadata + } +} + +/** + * An instance of lunr.MatchData will be created for every term that matches a + * document. However only one instance is required in a lunr.Index~Result. This + * method combines metadata from another instance of lunr.MatchData with this + * objects metadata. + * + * @param {lunr.MatchData} otherMatchData - Another instance of match data to merge with this one. + * @see {@link lunr.Index~Result} + */ +lunr.MatchData.prototype.combine = function (otherMatchData) { + var terms = Object.keys(otherMatchData.metadata) + + for (var i = 0; i < terms.length; i++) { + var term = terms[i], + fields = Object.keys(otherMatchData.metadata[term]) + + if (this.metadata[term] == undefined) { + this.metadata[term] = Object.create(null) + } + + for (var j = 0; j < fields.length; j++) { + var field = fields[j], + keys = Object.keys(otherMatchData.metadata[term][field]) + + if (this.metadata[term][field] == undefined) { + this.metadata[term][field] = Object.create(null) + } + + for (var k = 0; k < keys.length; k++) { + var key = keys[k] + + if (this.metadata[term][field][key] == undefined) { + this.metadata[term][field][key] = otherMatchData.metadata[term][field][key] + } else { + this.metadata[term][field][key] = this.metadata[term][field][key].concat(otherMatchData.metadata[term][field][key]) + } + + } + } + } +} + +/** + * Add metadata for a term/field pair to this instance of match data. + * + * @param {string} term - The term this match data is associated with + * @param {string} field - The field in which the term was found + * @param {object} metadata - The metadata recorded about this term in this field + */ +lunr.MatchData.prototype.add = function (term, field, metadata) { + if (!(term in this.metadata)) { + this.metadata[term] = Object.create(null) + this.metadata[term][field] = metadata + return + } + + if (!(field in this.metadata[term])) { + this.metadata[term][field] = metadata + return + } + + var metadataKeys = Object.keys(metadata) + + for (var i = 0; i < metadataKeys.length; i++) { + var key = metadataKeys[i] + + if (key in this.metadata[term][field]) { + this.metadata[term][field][key] = this.metadata[term][field][key].concat(metadata[key]) + } else { + this.metadata[term][field][key] = metadata[key] + } + } +} +/** + * A lunr.Query provides a programmatic way of defining queries to be performed + * against a {@link lunr.Index}. + * + * Prefer constructing a lunr.Query using the {@link lunr.Index#query} method + * so the query object is pre-initialized with the right index fields. + * + * @constructor + * @property {lunr.Query~Clause[]} clauses - An array of query clauses. + * @property {string[]} allFields - An array of all available fields in a lunr.Index. + */ +lunr.Query = function (allFields) { + this.clauses = [] + this.allFields = allFields +} + +/** + * Constants for indicating what kind of automatic wildcard insertion will be used when constructing a query clause. + * + * This allows wildcards to be added to the beginning and end of a term without having to manually do any string + * concatenation. + * + * The wildcard constants can be bitwise combined to select both leading and trailing wildcards. + * + * @constant + * @default + * @property {number} wildcard.NONE - The term will have no wildcards inserted, this is the default behaviour + * @property {number} wildcard.LEADING - Prepend the term with a wildcard, unless a leading wildcard already exists + * @property {number} wildcard.TRAILING - Append a wildcard to the term, unless a trailing wildcard already exists + * @see lunr.Query~Clause + * @see lunr.Query#clause + * @see lunr.Query#term + * @example query term with trailing wildcard + * query.term('foo', { wildcard: lunr.Query.wildcard.TRAILING }) + * @example query term with leading and trailing wildcard + * query.term('foo', { + * wildcard: lunr.Query.wildcard.LEADING | lunr.Query.wildcard.TRAILING + * }) + */ + +lunr.Query.wildcard = new String ("*") +lunr.Query.wildcard.NONE = 0 +lunr.Query.wildcard.LEADING = 1 +lunr.Query.wildcard.TRAILING = 2 + +/** + * Constants for indicating what kind of presence a term must have in matching documents. + * + * @constant + * @enum {number} + * @see lunr.Query~Clause + * @see lunr.Query#clause + * @see lunr.Query#term + * @example query term with required presence + * query.term('foo', { presence: lunr.Query.presence.REQUIRED }) + */ +lunr.Query.presence = { + /** + * Term's presence in a document is optional, this is the default value. + */ + OPTIONAL: 1, + + /** + * Term's presence in a document is required, documents that do not contain + * this term will not be returned. + */ + REQUIRED: 2, + + /** + * Term's presence in a document is prohibited, documents that do contain + * this term will not be returned. + */ + PROHIBITED: 3 +} + +/** + * A single clause in a {@link lunr.Query} contains a term and details on how to + * match that term against a {@link lunr.Index}. + * + * @typedef {Object} lunr.Query~Clause + * @property {string[]} fields - The fields in an index this clause should be matched against. + * @property {number} [boost=1] - Any boost that should be applied when matching this clause. + * @property {number} [editDistance] - Whether the term should have fuzzy matching applied, and how fuzzy the match should be. + * @property {boolean} [usePipeline] - Whether the term should be passed through the search pipeline. + * @property {number} [wildcard=lunr.Query.wildcard.NONE] - Whether the term should have wildcards appended or prepended. + * @property {number} [presence=lunr.Query.presence.OPTIONAL] - The terms presence in any matching documents. + */ + +/** + * Adds a {@link lunr.Query~Clause} to this query. + * + * Unless the clause contains the fields to be matched all fields will be matched. In addition + * a default boost of 1 is applied to the clause. + * + * @param {lunr.Query~Clause} clause - The clause to add to this query. + * @see lunr.Query~Clause + * @returns {lunr.Query} + */ +lunr.Query.prototype.clause = function (clause) { + if (!('fields' in clause)) { + clause.fields = this.allFields + } + + if (!('boost' in clause)) { + clause.boost = 1 + } + + if (!('usePipeline' in clause)) { + clause.usePipeline = true + } + + if (!('wildcard' in clause)) { + clause.wildcard = lunr.Query.wildcard.NONE + } + + if ((clause.wildcard & lunr.Query.wildcard.LEADING) && (clause.term.charAt(0) != lunr.Query.wildcard)) { + clause.term = "*" + clause.term + } + + if ((clause.wildcard & lunr.Query.wildcard.TRAILING) && (clause.term.slice(-1) != lunr.Query.wildcard)) { + clause.term = "" + clause.term + "*" + } + + if (!('presence' in clause)) { + clause.presence = lunr.Query.presence.OPTIONAL + } + + this.clauses.push(clause) + + return this +} + +/** + * A negated query is one in which every clause has a presence of + * prohibited. These queries require some special processing to return + * the expected results. + * + * @returns boolean + */ +lunr.Query.prototype.isNegated = function () { + for (var i = 0; i < this.clauses.length; i++) { + if (this.clauses[i].presence != lunr.Query.presence.PROHIBITED) { + return false + } + } + + return true +} + +/** + * Adds a term to the current query, under the covers this will create a {@link lunr.Query~Clause} + * to the list of clauses that make up this query. + * + * The term is used as is, i.e. no tokenization will be performed by this method. Instead conversion + * to a token or token-like string should be done before calling this method. + * + * The term will be converted to a string by calling `toString`. Multiple terms can be passed as an + * array, each term in the array will share the same options. + * + * @param {object|object[]} term - The term(s) to add to the query. + * @param {object} [options] - Any additional properties to add to the query clause. + * @returns {lunr.Query} + * @see lunr.Query#clause + * @see lunr.Query~Clause + * @example adding a single term to a query + * query.term("foo") + * @example adding a single term to a query and specifying search fields, term boost and automatic trailing wildcard + * query.term("foo", { + * fields: ["title"], + * boost: 10, + * wildcard: lunr.Query.wildcard.TRAILING + * }) + * @example using lunr.tokenizer to convert a string to tokens before using them as terms + * query.term(lunr.tokenizer("foo bar")) + */ +lunr.Query.prototype.term = function (term, options) { + if (Array.isArray(term)) { + term.forEach(function (t) { this.term(t, lunr.utils.clone(options)) }, this) + return this + } + + var clause = options || {} + clause.term = term.toString() + + this.clause(clause) + + return this +} +lunr.QueryParseError = function (message, start, end) { + this.name = "QueryParseError" + this.message = message + this.start = start + this.end = end +} + +lunr.QueryParseError.prototype = new Error +lunr.QueryLexer = function (str) { + this.lexemes = [] + this.str = str + this.length = str.length + this.pos = 0 + this.start = 0 + this.escapeCharPositions = [] +} + +lunr.QueryLexer.prototype.run = function () { + var state = lunr.QueryLexer.lexText + + while (state) { + state = state(this) + } +} + +lunr.QueryLexer.prototype.sliceString = function () { + var subSlices = [], + sliceStart = this.start, + sliceEnd = this.pos + + for (var i = 0; i < this.escapeCharPositions.length; i++) { + sliceEnd = this.escapeCharPositions[i] + subSlices.push(this.str.slice(sliceStart, sliceEnd)) + sliceStart = sliceEnd + 1 + } + + subSlices.push(this.str.slice(sliceStart, this.pos)) + this.escapeCharPositions.length = 0 + + return subSlices.join('') +} + +lunr.QueryLexer.prototype.emit = function (type) { + this.lexemes.push({ + type: type, + str: this.sliceString(), + start: this.start, + end: this.pos + }) + + this.start = this.pos +} + +lunr.QueryLexer.prototype.escapeCharacter = function () { + this.escapeCharPositions.push(this.pos - 1) + this.pos += 1 +} + +lunr.QueryLexer.prototype.next = function () { + if (this.pos >= this.length) { + return lunr.QueryLexer.EOS + } + + var char = this.str.charAt(this.pos) + this.pos += 1 + return char +} + +lunr.QueryLexer.prototype.width = function () { + return this.pos - this.start +} + +lunr.QueryLexer.prototype.ignore = function () { + if (this.start == this.pos) { + this.pos += 1 + } + + this.start = this.pos +} + +lunr.QueryLexer.prototype.backup = function () { + this.pos -= 1 +} + +lunr.QueryLexer.prototype.acceptDigitRun = function () { + var char, charCode + + do { + char = this.next() + charCode = char.charCodeAt(0) + } while (charCode > 47 && charCode < 58) + + if (char != lunr.QueryLexer.EOS) { + this.backup() + } +} + +lunr.QueryLexer.prototype.more = function () { + return this.pos < this.length +} + +lunr.QueryLexer.EOS = 'EOS' +lunr.QueryLexer.FIELD = 'FIELD' +lunr.QueryLexer.TERM = 'TERM' +lunr.QueryLexer.EDIT_DISTANCE = 'EDIT_DISTANCE' +lunr.QueryLexer.BOOST = 'BOOST' +lunr.QueryLexer.PRESENCE = 'PRESENCE' + +lunr.QueryLexer.lexField = function (lexer) { + lexer.backup() + lexer.emit(lunr.QueryLexer.FIELD) + lexer.ignore() + return lunr.QueryLexer.lexText +} + +lunr.QueryLexer.lexTerm = function (lexer) { + if (lexer.width() > 1) { + lexer.backup() + lexer.emit(lunr.QueryLexer.TERM) + } + + lexer.ignore() + + if (lexer.more()) { + return lunr.QueryLexer.lexText + } +} + +lunr.QueryLexer.lexEditDistance = function (lexer) { + lexer.ignore() + lexer.acceptDigitRun() + lexer.emit(lunr.QueryLexer.EDIT_DISTANCE) + return lunr.QueryLexer.lexText +} + +lunr.QueryLexer.lexBoost = function (lexer) { + lexer.ignore() + lexer.acceptDigitRun() + lexer.emit(lunr.QueryLexer.BOOST) + return lunr.QueryLexer.lexText +} + +lunr.QueryLexer.lexEOS = function (lexer) { + if (lexer.width() > 0) { + lexer.emit(lunr.QueryLexer.TERM) + } +} + +// This matches the separator used when tokenising fields +// within a document. These should match otherwise it is +// not possible to search for some tokens within a document. +// +// It is possible for the user to change the separator on the +// tokenizer so it _might_ clash with any other of the special +// characters already used within the search string, e.g. :. +// +// This means that it is possible to change the separator in +// such a way that makes some words unsearchable using a search +// string. +lunr.QueryLexer.termSeparator = lunr.tokenizer.separator + +lunr.QueryLexer.lexText = function (lexer) { + while (true) { + var char = lexer.next() + + if (char == lunr.QueryLexer.EOS) { + return lunr.QueryLexer.lexEOS + } + + // Escape character is '\' + if (char.charCodeAt(0) == 92) { + lexer.escapeCharacter() + continue + } + + if (char == ":") { + return lunr.QueryLexer.lexField + } + + if (char == "~") { + lexer.backup() + if (lexer.width() > 0) { + lexer.emit(lunr.QueryLexer.TERM) + } + return lunr.QueryLexer.lexEditDistance + } + + if (char == "^") { + lexer.backup() + if (lexer.width() > 0) { + lexer.emit(lunr.QueryLexer.TERM) + } + return lunr.QueryLexer.lexBoost + } + + // "+" indicates term presence is required + // checking for length to ensure that only + // leading "+" are considered + if (char == "+" && lexer.width() === 1) { + lexer.emit(lunr.QueryLexer.PRESENCE) + return lunr.QueryLexer.lexText + } + + // "-" indicates term presence is prohibited + // checking for length to ensure that only + // leading "-" are considered + if (char == "-" && lexer.width() === 1) { + lexer.emit(lunr.QueryLexer.PRESENCE) + return lunr.QueryLexer.lexText + } + + if (char.match(lunr.QueryLexer.termSeparator)) { + return lunr.QueryLexer.lexTerm + } + } +} + +lunr.QueryParser = function (str, query) { + this.lexer = new lunr.QueryLexer (str) + this.query = query + this.currentClause = {} + this.lexemeIdx = 0 +} + +lunr.QueryParser.prototype.parse = function () { + this.lexer.run() + this.lexemes = this.lexer.lexemes + + var state = lunr.QueryParser.parseClause + + while (state) { + state = state(this) + } + + return this.query +} + +lunr.QueryParser.prototype.peekLexeme = function () { + return this.lexemes[this.lexemeIdx] +} + +lunr.QueryParser.prototype.consumeLexeme = function () { + var lexeme = this.peekLexeme() + this.lexemeIdx += 1 + return lexeme +} + +lunr.QueryParser.prototype.nextClause = function () { + var completedClause = this.currentClause + this.query.clause(completedClause) + this.currentClause = {} +} + +lunr.QueryParser.parseClause = function (parser) { + var lexeme = parser.peekLexeme() + + if (lexeme == undefined) { + return + } + + switch (lexeme.type) { + case lunr.QueryLexer.PRESENCE: + return lunr.QueryParser.parsePresence + case lunr.QueryLexer.FIELD: + return lunr.QueryParser.parseField + case lunr.QueryLexer.TERM: + return lunr.QueryParser.parseTerm + default: + var errorMessage = "expected either a field or a term, found " + lexeme.type + + if (lexeme.str.length >= 1) { + errorMessage += " with value '" + lexeme.str + "'" + } + + throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end) + } +} + +lunr.QueryParser.parsePresence = function (parser) { + var lexeme = parser.consumeLexeme() + + if (lexeme == undefined) { + return + } + + switch (lexeme.str) { + case "-": + parser.currentClause.presence = lunr.Query.presence.PROHIBITED + break + case "+": + parser.currentClause.presence = lunr.Query.presence.REQUIRED + break + default: + var errorMessage = "unrecognised presence operator'" + lexeme.str + "'" + throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end) + } + + var nextLexeme = parser.peekLexeme() + + if (nextLexeme == undefined) { + var errorMessage = "expecting term or field, found nothing" + throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end) + } + + switch (nextLexeme.type) { + case lunr.QueryLexer.FIELD: + return lunr.QueryParser.parseField + case lunr.QueryLexer.TERM: + return lunr.QueryParser.parseTerm + default: + var errorMessage = "expecting term or field, found '" + nextLexeme.type + "'" + throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end) + } +} + +lunr.QueryParser.parseField = function (parser) { + var lexeme = parser.consumeLexeme() + + if (lexeme == undefined) { + return + } + + if (parser.query.allFields.indexOf(lexeme.str) == -1) { + var possibleFields = parser.query.allFields.map(function (f) { return "'" + f + "'" }).join(', '), + errorMessage = "unrecognised field '" + lexeme.str + "', possible fields: " + possibleFields + + throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end) + } + + parser.currentClause.fields = [lexeme.str] + + var nextLexeme = parser.peekLexeme() + + if (nextLexeme == undefined) { + var errorMessage = "expecting term, found nothing" + throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end) + } + + switch (nextLexeme.type) { + case lunr.QueryLexer.TERM: + return lunr.QueryParser.parseTerm + default: + var errorMessage = "expecting term, found '" + nextLexeme.type + "'" + throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end) + } +} + +lunr.QueryParser.parseTerm = function (parser) { + var lexeme = parser.consumeLexeme() + + if (lexeme == undefined) { + return + } + + parser.currentClause.term = lexeme.str.toLowerCase() + + if (lexeme.str.indexOf("*") != -1) { + parser.currentClause.usePipeline = false + } + + var nextLexeme = parser.peekLexeme() + + if (nextLexeme == undefined) { + parser.nextClause() + return + } + + switch (nextLexeme.type) { + case lunr.QueryLexer.TERM: + parser.nextClause() + return lunr.QueryParser.parseTerm + case lunr.QueryLexer.FIELD: + parser.nextClause() + return lunr.QueryParser.parseField + case lunr.QueryLexer.EDIT_DISTANCE: + return lunr.QueryParser.parseEditDistance + case lunr.QueryLexer.BOOST: + return lunr.QueryParser.parseBoost + case lunr.QueryLexer.PRESENCE: + parser.nextClause() + return lunr.QueryParser.parsePresence + default: + var errorMessage = "Unexpected lexeme type '" + nextLexeme.type + "'" + throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end) + } +} + +lunr.QueryParser.parseEditDistance = function (parser) { + var lexeme = parser.consumeLexeme() + + if (lexeme == undefined) { + return + } + + var editDistance = parseInt(lexeme.str, 10) + + if (isNaN(editDistance)) { + var errorMessage = "edit distance must be numeric" + throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end) + } + + parser.currentClause.editDistance = editDistance + + var nextLexeme = parser.peekLexeme() + + if (nextLexeme == undefined) { + parser.nextClause() + return + } + + switch (nextLexeme.type) { + case lunr.QueryLexer.TERM: + parser.nextClause() + return lunr.QueryParser.parseTerm + case lunr.QueryLexer.FIELD: + parser.nextClause() + return lunr.QueryParser.parseField + case lunr.QueryLexer.EDIT_DISTANCE: + return lunr.QueryParser.parseEditDistance + case lunr.QueryLexer.BOOST: + return lunr.QueryParser.parseBoost + case lunr.QueryLexer.PRESENCE: + parser.nextClause() + return lunr.QueryParser.parsePresence + default: + var errorMessage = "Unexpected lexeme type '" + nextLexeme.type + "'" + throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end) + } +} + +lunr.QueryParser.parseBoost = function (parser) { + var lexeme = parser.consumeLexeme() + + if (lexeme == undefined) { + return + } + + var boost = parseInt(lexeme.str, 10) + + if (isNaN(boost)) { + var errorMessage = "boost must be numeric" + throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end) + } + + parser.currentClause.boost = boost + + var nextLexeme = parser.peekLexeme() + + if (nextLexeme == undefined) { + parser.nextClause() + return + } + + switch (nextLexeme.type) { + case lunr.QueryLexer.TERM: + parser.nextClause() + return lunr.QueryParser.parseTerm + case lunr.QueryLexer.FIELD: + parser.nextClause() + return lunr.QueryParser.parseField + case lunr.QueryLexer.EDIT_DISTANCE: + return lunr.QueryParser.parseEditDistance + case lunr.QueryLexer.BOOST: + return lunr.QueryParser.parseBoost + case lunr.QueryLexer.PRESENCE: + parser.nextClause() + return lunr.QueryParser.parsePresence + default: + var errorMessage = "Unexpected lexeme type '" + nextLexeme.type + "'" + throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end) + } +} + + /** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ + ;(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like enviroments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + root.lunr = factory() + } + }(this, function () { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + return lunr + })) +})(); diff --git a/assets/js/lunr/lunr.min.js b/assets/js/lunr/lunr.min.js new file mode 100644 index 000000000..cdc94cd39 --- /dev/null +++ b/assets/js/lunr/lunr.min.js @@ -0,0 +1,6 @@ +/** + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 + * Copyright (C) 2020 Oliver Nightingale + * @license MIT + */ +!function(){var e=function(t){var r=new e.Builder;return r.pipeline.add(e.trimmer,e.stopWordFilter,e.stemmer),r.searchPipeline.add(e.stemmer),t.call(r,r),r.build()};e.version="2.3.9",e.utils={},e.utils.warn=function(e){return function(t){e.console&&console.warn&&console.warn(t)}}(this),e.utils.asString=function(e){return void 0===e||null===e?"":e.toString()},e.utils.clone=function(e){if(null===e||void 0===e)return e;for(var t=Object.create(null),r=Object.keys(e),i=0;i0){var c=e.utils.clone(r)||{};c.position=[a,l],c.index=s.length,s.push(new e.Token(i.slice(a,o),c))}a=o+1}}return s},e.tokenizer.separator=/[\s\-]+/,e.Pipeline=function(){this._stack=[]},e.Pipeline.registeredFunctions=Object.create(null),e.Pipeline.registerFunction=function(t,r){r in this.registeredFunctions&&e.utils.warn("Overwriting existing registered function: "+r),t.label=r,e.Pipeline.registeredFunctions[t.label]=t},e.Pipeline.warnIfFunctionNotRegistered=function(t){var r=t.label&&t.label in this.registeredFunctions;r||e.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",t)},e.Pipeline.load=function(t){var r=new e.Pipeline;return t.forEach(function(t){var i=e.Pipeline.registeredFunctions[t];if(!i)throw new Error("Cannot load unregistered function: "+t);r.add(i)}),r},e.Pipeline.prototype.add=function(){var t=Array.prototype.slice.call(arguments);t.forEach(function(t){e.Pipeline.warnIfFunctionNotRegistered(t),this._stack.push(t)},this)},e.Pipeline.prototype.after=function(t,r){e.Pipeline.warnIfFunctionNotRegistered(r);var i=this._stack.indexOf(t);if(i==-1)throw new Error("Cannot find existingFn");i+=1,this._stack.splice(i,0,r)},e.Pipeline.prototype.before=function(t,r){e.Pipeline.warnIfFunctionNotRegistered(r);var i=this._stack.indexOf(t);if(i==-1)throw new Error("Cannot find existingFn");this._stack.splice(i,0,r)},e.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);t!=-1&&this._stack.splice(t,1)},e.Pipeline.prototype.run=function(e){for(var t=this._stack.length,r=0;r1&&(se&&(r=n),s!=e);)i=r-t,n=t+Math.floor(i/2),s=this.elements[2*n];return s==e?2*n:s>e?2*n:sa?l+=2:o==a&&(t+=r[u+1]*i[l+1],u+=2,l+=2);return t},e.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},e.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,r=0;t0){var o,a=s.str.charAt(0);a in s.node.edges?o=s.node.edges[a]:(o=new e.TokenSet,s.node.edges[a]=o),1==s.str.length&&(o["final"]=!0),n.push({node:o,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(0!=s.editsRemaining){if("*"in s.node.edges)var u=s.node.edges["*"];else{var u=new e.TokenSet;s.node.edges["*"]=u}if(0==s.str.length&&(u["final"]=!0),n.push({node:u,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&n.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),1==s.str.length&&(s.node["final"]=!0),s.str.length>=1){if("*"in s.node.edges)var l=s.node.edges["*"];else{var l=new e.TokenSet;s.node.edges["*"]=l}1==s.str.length&&(l["final"]=!0),n.push({node:l,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var c,h=s.str.charAt(0),d=s.str.charAt(1);d in s.node.edges?c=s.node.edges[d]:(c=new e.TokenSet,s.node.edges[d]=c),1==s.str.length&&(c["final"]=!0),n.push({node:c,editsRemaining:s.editsRemaining-1,str:h+s.str.slice(2)})}}}return i},e.TokenSet.fromString=function(t){for(var r=new e.TokenSet,i=r,n=0,s=t.length;n=e;t--){var r=this.uncheckedNodes[t],i=r.child.toString();i in this.minimizedNodes?r.parent.edges[r["char"]]=this.minimizedNodes[i]:(r.child._str=i,this.minimizedNodes[i]=r.child),this.uncheckedNodes.pop()}},e.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},e.Index.prototype.search=function(t){return this.query(function(r){var i=new e.QueryParser(t,r);i.parse()})},e.Index.prototype.query=function(t){for(var r=new e.Query(this.fields),i=Object.create(null),n=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),u=0;u1?this._b=1:this._b=e},e.Builder.prototype.k1=function(e){this._k1=e},e.Builder.prototype.add=function(t,r){var i=t[this._ref],n=Object.keys(this._fields);this._documents[i]=r||{},this.documentCount+=1;for(var s=0;s=this.length)return e.QueryLexer.EOS;var t=this.str.charAt(this.pos);return this.pos+=1,t},e.QueryLexer.prototype.width=function(){return this.pos-this.start},e.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},e.QueryLexer.prototype.backup=function(){this.pos-=1},e.QueryLexer.prototype.acceptDigitRun=function(){var t,r;do t=this.next(),r=t.charCodeAt(0);while(r>47&&r<58);t!=e.QueryLexer.EOS&&this.backup()},e.QueryLexer.prototype.more=function(){return this.pos1&&(t.backup(),t.emit(e.QueryLexer.TERM)),t.ignore(),t.more())return e.QueryLexer.lexText},e.QueryLexer.lexEditDistance=function(t){return t.ignore(),t.acceptDigitRun(),t.emit(e.QueryLexer.EDIT_DISTANCE),e.QueryLexer.lexText},e.QueryLexer.lexBoost=function(t){return t.ignore(),t.acceptDigitRun(),t.emit(e.QueryLexer.BOOST),e.QueryLexer.lexText},e.QueryLexer.lexEOS=function(t){t.width()>0&&t.emit(e.QueryLexer.TERM)},e.QueryLexer.termSeparator=e.tokenizer.separator,e.QueryLexer.lexText=function(t){for(;;){var r=t.next();if(r==e.QueryLexer.EOS)return e.QueryLexer.lexEOS;if(92!=r.charCodeAt(0)){if(":"==r)return e.QueryLexer.lexField;if("~"==r)return t.backup(),t.width()>0&&t.emit(e.QueryLexer.TERM),e.QueryLexer.lexEditDistance;if("^"==r)return t.backup(),t.width()>0&&t.emit(e.QueryLexer.TERM),e.QueryLexer.lexBoost;if("+"==r&&1===t.width())return t.emit(e.QueryLexer.PRESENCE),e.QueryLexer.lexText;if("-"==r&&1===t.width())return t.emit(e.QueryLexer.PRESENCE),e.QueryLexer.lexText;if(r.match(e.QueryLexer.termSeparator))return e.QueryLexer.lexTerm}else t.escapeCharacter()}},e.QueryParser=function(t,r){this.lexer=new e.QueryLexer(t),this.query=r,this.currentClause={},this.lexemeIdx=0},e.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var t=e.QueryParser.parseClause;t;)t=t(this);return this.query},e.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},e.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},e.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},e.QueryParser.parseClause=function(t){var r=t.peekLexeme();if(void 0!=r)switch(r.type){case e.QueryLexer.PRESENCE:return e.QueryParser.parsePresence;case e.QueryLexer.FIELD:return e.QueryParser.parseField;case e.QueryLexer.TERM:return e.QueryParser.parseTerm;default:var i="expected either a field or a term, found "+r.type;throw r.str.length>=1&&(i+=" with value '"+r.str+"'"),new e.QueryParseError(i,r.start,r.end)}},e.QueryParser.parsePresence=function(t){var r=t.consumeLexeme();if(void 0!=r){switch(r.str){case"-":t.currentClause.presence=e.Query.presence.PROHIBITED;break;case"+":t.currentClause.presence=e.Query.presence.REQUIRED;break;default:var i="unrecognised presence operator'"+r.str+"'";throw new e.QueryParseError(i,r.start,r.end)}var n=t.peekLexeme();if(void 0==n){var i="expecting term or field, found nothing";throw new e.QueryParseError(i,r.start,r.end)}switch(n.type){case e.QueryLexer.FIELD:return e.QueryParser.parseField;case e.QueryLexer.TERM:return e.QueryParser.parseTerm;default:var i="expecting term or field, found '"+n.type+"'";throw new e.QueryParseError(i,n.start,n.end)}}},e.QueryParser.parseField=function(t){var r=t.consumeLexeme();if(void 0!=r){if(t.query.allFields.indexOf(r.str)==-1){var i=t.query.allFields.map(function(e){return"'"+e+"'"}).join(", "),n="unrecognised field '"+r.str+"', possible fields: "+i;throw new e.QueryParseError(n,r.start,r.end)}t.currentClause.fields=[r.str];var s=t.peekLexeme();if(void 0==s){var n="expecting term, found nothing";throw new e.QueryParseError(n,r.start,r.end)}switch(s.type){case e.QueryLexer.TERM:return e.QueryParser.parseTerm;default:var n="expecting term, found '"+s.type+"'";throw new e.QueryParseError(n,s.start,s.end)}}},e.QueryParser.parseTerm=function(t){var r=t.consumeLexeme();if(void 0!=r){t.currentClause.term=r.str.toLowerCase(),r.str.indexOf("*")!=-1&&(t.currentClause.usePipeline=!1);var i=t.peekLexeme();if(void 0==i)return void t.nextClause();switch(i.type){case e.QueryLexer.TERM:return t.nextClause(),e.QueryParser.parseTerm;case e.QueryLexer.FIELD:return t.nextClause(),e.QueryParser.parseField;case e.QueryLexer.EDIT_DISTANCE:return e.QueryParser.parseEditDistance;case e.QueryLexer.BOOST:return e.QueryParser.parseBoost;case e.QueryLexer.PRESENCE:return t.nextClause(),e.QueryParser.parsePresence;default:var n="Unexpected lexeme type '"+i.type+"'";throw new e.QueryParseError(n,i.start,i.end)}}},e.QueryParser.parseEditDistance=function(t){var r=t.consumeLexeme();if(void 0!=r){var i=parseInt(r.str,10);if(isNaN(i)){var n="edit distance must be numeric";throw new e.QueryParseError(n,r.start,r.end)}t.currentClause.editDistance=i;var s=t.peekLexeme();if(void 0==s)return void t.nextClause();switch(s.type){case e.QueryLexer.TERM:return t.nextClause(),e.QueryParser.parseTerm;case e.QueryLexer.FIELD:return t.nextClause(),e.QueryParser.parseField;case e.QueryLexer.EDIT_DISTANCE:return e.QueryParser.parseEditDistance;case e.QueryLexer.BOOST:return e.QueryParser.parseBoost;case e.QueryLexer.PRESENCE:return t.nextClause(),e.QueryParser.parsePresence;default:var n="Unexpected lexeme type '"+s.type+"'";throw new e.QueryParseError(n,s.start,s.end)}}},e.QueryParser.parseBoost=function(t){var r=t.consumeLexeme();if(void 0!=r){var i=parseInt(r.str,10);if(isNaN(i)){var n="boost must be numeric";throw new e.QueryParseError(n,r.start,r.end)}t.currentClause.boost=i;var s=t.peekLexeme();if(void 0==s)return void t.nextClause();switch(s.type){case e.QueryLexer.TERM:return t.nextClause(),e.QueryParser.parseTerm;case e.QueryLexer.FIELD:return t.nextClause(),e.QueryParser.parseField;case e.QueryLexer.EDIT_DISTANCE:return e.QueryParser.parseEditDistance;case e.QueryLexer.BOOST:return e.QueryParser.parseBoost;case e.QueryLexer.PRESENCE:return t.nextClause(),e.QueryParser.parsePresence;default:var n="Unexpected lexeme type '"+s.type+"'";throw new e.QueryParseError(n,s.start,s.end)}}},function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():e.lunr=t()}(this,function(){return e})}(); diff --git a/assets/js/main.min.js b/assets/js/main.min.js new file mode 100644 index 000000000..8b2983ecd --- /dev/null +++ b/assets/js/main.min.js @@ -0,0 +1,6 @@ +/*! + * Minimal Mistakes Jekyll Theme 4.24.0 by Michael Rose + * Copyright 2013-2021 Michael Rose - mademistakes.com | @mmistakes + * Licensed under MIT + */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";function m(e){return null!=e&&e===e.window}var t=[],n=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,o=t.indexOf,r={},i=r.toString,v=r.hasOwnProperty,a=v.toString,l=a.call(Object),y={},b=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},T=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function x(e,t,n){var r,o,i=(n=n||T).createElement("script");if(i.text=e,t)for(r in c)(o=t[r]||t.getAttribute&&t.getAttribute(r))&&i.setAttribute(r,o);n.head.appendChild(i).parentNode.removeChild(i)}function h(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?r[i.call(e)]||"object":typeof e}var f="3.5.1",E=function(e,t){return new E.fn.init(e,t)};function d(e){var t=!!e&&"length"in e&&e.length,n=h(e);return!b(e)&&!m(e)&&("array"===n||0===t||"number"==typeof t&&0>10|55296,1023&e|56320))}function r(){C()}var e,d,x,i,o,p,h,m,w,u,l,C,T,a,E,g,s,c,v,S="sizzle"+ +new Date,y=n.document,k=0,b=0,A=ue(),N=ue(),j=ue(),I=ue(),L=function(e,t){return e===t&&(l=!0),0},D={}.hasOwnProperty,t=[],O=t.pop,H=t.push,P=t.push,q=t.slice,M=function(e,t){for(var n=0,r=e.length;n+~]|"+$+")"+$+"*"),Q=new RegExp($+"|>"),Y=new RegExp(F),V=new RegExp("^"+R+"$"),G={ID:new RegExp("^#("+R+")"),CLASS:new RegExp("^\\.("+R+")"),TAG:new RegExp("^("+R+"|[*])"),ATTR:new RegExp("^"+B),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+$+"*(even|odd|(([+-]|)(\\d*)n|)"+$+"*(?:([+-]|)"+$+"*(\\d+)|))"+$+"*\\)|)","i"),bool:new RegExp("^(?:"+_+")$","i"),needsContext:new RegExp("^"+$+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+$+"*((?:-\\d)?\\d*)"+$+"*\\)|)(?=[^-]|$)","i")},K=/HTML$/i,Z=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,ee=/^[^{]+\{\s*\[native \w/,te=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ne=/[+~]/,re=new RegExp("\\\\[\\da-fA-F]{1,6}"+$+"?|\\\\([^\\r\\n\\f])","g"),oe=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},ae=ye(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{P.apply(t=q.call(y.childNodes),y.childNodes),t[y.childNodes.length].nodeType}catch(e){P={apply:t.length?function(e,t){H.apply(e,q.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}function se(t,e,n,r){var o,i,a,s,u,l,c=e&&e.ownerDocument,f=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==f&&9!==f&&11!==f)return n;if(!r&&(C(e),e=e||T,E)){if(11!==f&&(s=te.exec(t)))if(l=s[1]){if(9===f){if(!(i=e.getElementById(l)))return n;if(i.id===l)return n.push(i),n}else if(c&&(i=c.getElementById(l))&&v(e,i)&&i.id===l)return n.push(i),n}else{if(s[2])return P.apply(n,e.getElementsByTagName(t)),n;if((l=s[3])&&d.getElementsByClassName&&e.getElementsByClassName)return P.apply(n,e.getElementsByClassName(l)),n}if(d.qsa&&!I[t+" "]&&(!g||!g.test(t))&&(1!==f||"object"!==e.nodeName.toLowerCase())){if(l=t,c=e,1===f&&(Q.test(t)||X.test(t))){for((c=ne.test(t)&&me(e.parentNode)||e)===e&&d.scope||((a=e.getAttribute("id"))?a=a.replace(oe,ie):e.setAttribute("id",a=S)),o=(u=p(t)).length;o--;)u[o]=(a?"#"+a:":scope")+" "+ve(u[o]);l=u.join(",")}try{return P.apply(n,c.querySelectorAll(l)),n}catch(e){I(t,!0)}finally{a===S&&e.removeAttribute("id")}}}return m(t.replace(W,"$1"),e,n,r)}function ue(){var n=[];function r(e,t){return n.push(e+" ")>x.cacheLength&&delete r[n.shift()],r[e+" "]=t}return r}function le(e){return e[S]=!0,e}function ce(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){for(var n=e.split("|"),r=n.length;r--;)x.attrHandle[n[r]]=t}function de(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function pe(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function he(a){return le(function(i){return i=+i,le(function(e,t){for(var n,r=a([],e.length,i),o=r.length;o--;)e[n=r[o]]&&(e[n]=!(t[n]=e[n]))})})}function me(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in d=se.support={},o=se.isXML=function(e){var t=e.namespaceURI,e=(e.ownerDocument||e).documentElement;return!K.test(t||e&&e.nodeName||"HTML")},C=se.setDocument=function(e){var t,e=e?e.ownerDocument||e:y;return e!=T&&9===e.nodeType&&e.documentElement&&(a=(T=e).documentElement,E=!o(T),y!=T&&(t=T.defaultView)&&t.top!==t&&(t.addEventListener?t.addEventListener("unload",r,!1):t.attachEvent&&t.attachEvent("onunload",r)),d.scope=ce(function(e){return a.appendChild(e).appendChild(T.createElement("div")),void 0!==e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(T.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=ee.test(T.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!T.getElementsByName||!T.getElementsByName(S).length}),d.getById?(x.filter.ID=function(e){var t=e.replace(re,f);return function(e){return e.getAttribute("id")===t}},x.find.ID=function(e,t){if(void 0!==t.getElementById&&E){e=t.getElementById(e);return e?[e]:[]}}):(x.filter.ID=function(e){var t=e.replace(re,f);return function(e){e=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return e&&e.value===t}},x.find.ID=function(e,t){if(void 0!==t.getElementById&&E){var n,r,o,i=t.getElementById(e);if(i){if((n=i.getAttributeNode("id"))&&n.value===e)return[i];for(o=t.getElementsByName(e),r=0;i=o[r++];)if((n=i.getAttributeNode("id"))&&n.value===e)return[i]}return[]}}),x.find.TAG=d.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],o=0,i=t.getElementsByTagName(e);if("*"!==e)return i;for(;n=i[o++];)1===n.nodeType&&r.push(n);return r},x.find.CLASS=d.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],g=[],(d.qsa=ee.test(T.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&g.push("[*^$]="+$+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||g.push("\\["+$+"*(?:value|"+_+")"),e.querySelectorAll("[id~="+S+"-]").length||g.push("~="),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||g.push("\\["+$+"*name"+$+"*="+$+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||g.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||g.push(".#.+[+~]"),e.querySelectorAll("\\\f"),g.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=T.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&g.push("name"+$+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&g.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(d.matchesSelector=ee.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),g=g.length&&new RegExp(g.join("|")),s=s.length&&new RegExp(s.join("|")),t=ee.test(a.compareDocumentPosition),v=t||ee.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,t=t&&t.parentNode;return e===t||!(!t||1!==t.nodeType||!(n.contains?n.contains(t):e.compareDocumentPosition&&16&e.compareDocumentPosition(t)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},L=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==T||e.ownerDocument==y&&v(y,e)?-1:t==T||t.ownerDocument==y&&v(y,t)?1:u?M(u,e)-M(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,o=e.parentNode,i=t.parentNode,a=[e],s=[t];if(!o||!i)return e==T?-1:t==T?1:o?-1:i?1:u?M(u,e)-M(u,t):0;if(o===i)return de(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;a[r]===s[r];)r++;return r?de(a[r],s[r]):a[r]==y?-1:s[r]==y?1:0}),T},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(C(e),d.matchesSelector&&E&&!I[t+" "]&&(!s||!s.test(t))&&(!g||!g.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){I(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(re,f),e[3]=(e[3]||e[4]||e[5]||"").replace(re,f),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&Y.test(n)&&(t=p(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(re,f).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=A[e+" "];return t||(t=new RegExp("(^|"+$+")"+e+"("+$+"|$)"))&&A(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(t,n,r){return function(e){e=se.attr(e,t);return null==e?"!="===n:!n||(e+="","="===n?e===r:"!="===n?e!==r:"^="===n?r&&0===e.indexOf(r):"*="===n?r&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return b(n)?E.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?E.grep(e,function(e){return e===n!==r}):"string"!=typeof n?E.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(E.fn.init=function(e,t,n){if(!e)return this;if(n=n||L,"string"!=typeof e)return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(E):E.makeArray(e,this);if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:I.exec(e))||!r[1]&&t)return(!t||t.jquery?t||n:this.constructor(t)).find(e);if(r[1]){if(t=t instanceof E?t[0]:t,E.merge(this,E.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:T,!0)),N.test(r[1])&&E.isPlainObject(t))for(var r in t)b(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(e=T.getElementById(r[2]))&&(this[0]=e,this.length=1),this}).prototype=E.fn;var L=E(T),D=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function H(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}E.fn.extend({has:function(e){var t=E(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,de=/^$|^module$|\/(?:java|ecma)script/i;f=T.createDocumentFragment().appendChild(T.createElement("div")),(p=T.createElement("input")).setAttribute("type","radio"),p.setAttribute("checked","checked"),p.setAttribute("name","t"),f.appendChild(p),y.checkClone=f.cloneNode(!0).cloneNode(!0).lastChild.checked,f.innerHTML="",y.noCloneChecked=!!f.cloneNode(!0).lastChild.defaultValue,f.innerHTML="",y.option=!!f.lastChild;var pe={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function he(e,t){var n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[];return void 0===t||t&&A(e,t)?E.merge([e],n):n}function me(e,t){for(var n=0,r=e.length;n",""]);var ge=/<|&#?\w+;/;function ve(e,t,n,r,o){for(var i,a,s,u,l,c=t.createDocumentFragment(),f=[],d=0,p=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&E(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Le(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function De(e,t){var n,r,o,i;if(1===t.nodeType){if(V.hasData(e)&&(i=V.get(e).events))for(o in V.remove(t,"handle events"),i)for(n=0,r=i[o].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",o=function(e){r.remove(),o=null,e&&t("error"===e.type?404:200,e.type)}),T.head.appendChild(r[0])},abort:function(){o&&o()}}});var Gt=[],Kt=/(=)\?(?=&|$)|\?\?/;E.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||E.expando+"_"+jt.guid++;return this[e]=!0,e}}),E.ajaxPrefilter("json jsonp",function(e,t,n){var r,o,i,a=!1!==e.jsonp&&(Kt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Kt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=b(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Kt,"$1"+r):!1!==e.jsonp&&(e.url+=(It.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return i||E.error(r+" was not called"),i[0]},e.dataTypes[0]="json",o=C[r],C[r]=function(){i=arguments},n.always(function(){void 0===o?E(C).removeProp(r):C[r]=o,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),i&&b(o)&&o(i[0]),i=o=void 0}),"script"}),y.createHTMLDocument=((f=T.implementation.createHTMLDocument("").body).innerHTML="
",2===f.childNodes.length),E.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=T.implementation.createHTMLDocument("")).createElement("base")).href=T.location.href,t.head.appendChild(r)):t=T),r=!n&&[],(n=N.exec(e))?[t.createElement(n[1])]:(n=ve([e],t,r),r&&r.length&&E(r).remove(),E.merge([],n.childNodes)));var r},E.fn.load=function(e,t,n){var r,o,i,a=this,s=e.indexOf(" ");return-1").append(E.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,i||[e.responseText,t,e])})}),this},E.expr.pseudos.animated=function(t){return E.grep(E.timers,function(e){return t===e.elem}).length},E.offset={setOffset:function(e,t,n){var r,o,i,a,s=E.css(e,"position"),u=E(e),l={};"static"===s&&(e.style.position="relative"),i=u.offset(),r=E.css(e,"top"),a=E.css(e,"left"),a=("absolute"===s||"fixed"===s)&&-1<(r+a).indexOf("auto")?(o=(s=u.position()).top,s.left):(o=parseFloat(r)||0,parseFloat(a)||0),null!=(t=b(t)?t.call(e,n,E.extend({},i)):t).top&&(l.top=t.top-i.top+o),null!=t.left&&(l.left=t.left-i.left+a),"using"in t?t.using.call(e,l):("number"==typeof l.top&&(l.top+="px"),"number"==typeof l.left&&(l.left+="px"),u.css(l))}},E.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){E.offset.setOffset(this,t,e)});var e,n=this[0];return n?n.getClientRects().length?(e=n.getBoundingClientRect(),n=n.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],o={top:0,left:0};if("fixed"===E.css(r,"position"))t=r.getBoundingClientRect();else{for(t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&"static"===E.css(e,"position");)e=e.parentNode;e&&e!==r&&1===e.nodeType&&((o=E(e).offset()).top+=E.css(e,"borderTopWidth",!0),o.left+=E.css(e,"borderLeftWidth",!0))}return{top:t.top-o.top-E.css(r,"marginTop",!0),left:t.left-o.left-E.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&"static"===E.css(e,"position");)e=e.offsetParent;return e||re})}}),E.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,o){var i="pageYOffset"===o;E.fn[t]=function(e){return F(this,function(e,t,n){var r;return m(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n?r?r[o]:e[t]:void(r?r.scrollTo(i?r.pageXOffset:n,i?n:r.pageYOffset):e[t]=n)},t,e,arguments.length)}}),E.each(["top","left"],function(e,n){E.cssHooks[n]=Ge(y.pixelPosition,function(e,t){if(t)return t=Ve(e,n),We.test(t)?E(e).position()[n]+"px":t})}),E.each({Height:"height",Width:"width"},function(a,s){E.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,i){E.fn[i]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),o=r||(!0===e||!0===t?"margin":"border");return F(this,function(e,t,n){var r;return m(e)?0===i.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?E.css(e,t,o):E.style(e,t,n,o)},s,n?e:void 0,n)}})}),E.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){E.fn[t]=function(e){return this.on(t,e)}}),E.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),E.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){E.fn[n]=function(e,t){return 0x

',t.appendChild(n.childNodes[1])),e&&i.extend(o,e),this.each(function(){var e=['iframe[src*="player.vimeo.com"]','iframe[src*="youtube.com"]','iframe[src*="youtube-nocookie.com"]','iframe[src*="kickstarter.com"][src*="video.html"]',"object","embed"];o.customSelector&&e.push(o.customSelector);var r=".fitvidsignore";o.ignore&&(r=r+", "+o.ignore);e=i(this).find(e.join(","));(e=(e=e.not("object object")).not(r)).each(function(e){var t,n=i(this);0').parent(".fluid-width-video-wrapper").css("padding-top",100*t+"%"),n.removeAttr("height").removeAttr("width"))})})}}(window.jQuery||window.Zepto),$(function(){var n,r,e,o,t=$("nav.greedy-nav .greedy-nav__toggle"),i=$("nav.greedy-nav .visible-links"),a=$("nav.greedy-nav .hidden-links"),s=$("nav.greedy-nav"),u=$("nav.greedy-nav .site-logo"),l=$("nav.greedy-nav .site-logo img"),c=$("nav.greedy-nav .site-title"),f=$("nav.greedy-nav button.search__toggle");function d(){function t(e,t){r+=t,n+=1,o.push(r)}r=n=0,e=1e3,o=[],i.children().outerWidth(t),a.children().each(function(){var e;(e=(e=$(this)).clone()).css("visibility","hidden"),i.append(e),t(0,e.outerWidth()),e.remove()})}d();var p,h,m,g,v=$(window).width(),y=v<768?0:v<1024?1:v<1280?2:3;function b(){var e=(v=$(window).width())<768?0:v<1024?1:v<1280?2:3;e!==y&&d(),y=e,h=i.children().length,p=s.innerWidth()-(0!==u.length?u.outerWidth(!0):0)-c.outerWidth(!0)-(0!==f.length?f.outerWidth(!0):0)-(h!==o.length?t.outerWidth(!0):0),m=o[h-1],po[h]&&(a.children().first().appendTo(i),h+=1,b()),t.attr("count",n-h),h===n?t.addClass("hidden"):t.removeClass("hidden")}$(window).resize(function(){b()}),t.on("click",function(){a.toggleClass("hidden"),$(this).toggleClass("close"),clearTimeout(g)}),a.on("mouseleave",function(){g=setTimeout(function(){a.addClass("hidden")},e)}).on("mouseenter",function(){clearTimeout(g)}),0===l.length||l[0].complete||0!==l[0].naturalWidth?b():l.one("load error",b)}),function(e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof exports?e(require("jquery")):e(window.jQuery||window.Zepto)}(function(l){function e(){}function c(e,t){h.ev.on("mfp"+e+x,t)}function f(e,t,n,r){var o=document.createElement("div");return o.className="mfp-"+e,n&&(o.innerHTML=n),r?t&&t.appendChild(o):(o=l(o),t&&o.appendTo(t)),o}function d(e,t){h.ev.triggerHandler("mfp"+e,t),h.st.callbacks&&(e=e.charAt(0).toLowerCase()+e.slice(1),h.st.callbacks[e]&&h.st.callbacks[e].apply(h,l.isArray(t)?t:[t]))}function p(e){return e===t&&h.currTemplate.closeBtn||(h.currTemplate.closeBtn=l(h.st.closeMarkup.replace("%title%",h.st.tClose)),t=e),h.currTemplate.closeBtn}function i(){l.magnificPopup.instance||((h=new e).init(),l.magnificPopup.instance=h)}var h,r,m,o,g,t,u="Close",v="BeforeClose",y="MarkupParse",b="Open",x=".mfp",w="mfp-ready",n="mfp-removing",a="mfp-prevent-close",s=!!window.jQuery,C=l(window);e.prototype={constructor:e,init:function(){var e=navigator.appVersion;h.isLowIE=h.isIE8=document.all&&!document.addEventListener,h.isAndroid=/android/gi.test(e),h.isIOS=/iphone|ipad|ipod/gi.test(e),h.supportsTransition=function(){var e=document.createElement("p").style,t=["ms","O","Moz","Webkit"];if(void 0!==e.transition)return!0;for(;t.length;)if(t.pop()+"Transition"in e)return!0;return!1}(),h.probablyMobile=h.isAndroid||h.isIOS||/(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent),m=l(document),h.popupsCache={}},open:function(e){if(!1===e.isObj){h.items=e.items.toArray(),h.index=0;for(var t,n=e.items,r=0;r(e||C.height())},_setFocus:function(){(h.st.focus?h.content.find(h.st.focus).eq(0):h.wrap).focus()},_onFocusIn:function(e){if(e.target!==h.wrap[0]&&!l.contains(h.wrap[0],e.target))return h._setFocus(),!1},_parseMarkup:function(o,e,t){var i;t.data&&(e=l.extend(t.data,e)),d(y,[o,e,t]),l.each(e,function(e,t){return void 0===t||!1===t||void(1<(i=e.split("_")).length?0<(n=o.find(x+"-"+i[0])).length&&("replaceWith"===(r=i[1])?n[0]!==t[0]&&n.replaceWith(t):"img"===r?n.is("img")?n.attr("src",t):n.replaceWith(l("").attr("src",t).attr("class",n.attr("class"))):n.attr(i[1],t)):o.find(x+"-"+e).html(t));var n,r})},_getScrollbarSize:function(){var e;return void 0===h.scrollbarSize&&((e=document.createElement("div")).style.cssText="width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;",document.body.appendChild(e),h.scrollbarSize=e.offsetWidth-e.clientWidth,document.body.removeChild(e)),h.scrollbarSize}},l.magnificPopup={instance:null,proto:e.prototype,modules:[],open:function(e,t){return i(),(e=e?l.extend(!0,{},e):{}).isObj=!0,e.index=t||0,this.instance.open(e)},close:function(){return l.magnificPopup.instance&&l.magnificPopup.instance.close()},registerModule:function(e,t){t.options&&(l.magnificPopup.defaults[e]=t.options),l.extend(this.proto,t.proto),this.modules.push(e)},defaults:{disableOn:0,key:null,midClick:!1,mainClass:"",preloader:!0,focus:"",closeOnContentClick:!1,closeOnBgClick:!0,closeBtnInside:!0,showCloseBtn:!0,enableEscapeKey:!0,modal:!1,alignTop:!1,removalDelay:0,prependTo:null,fixedContentPos:"auto",fixedBgPos:"auto",overflowY:"auto",closeMarkup:'',tClose:"Close (Esc)",tLoading:"Loading...",autoFocusLast:!0}},l.fn.magnificPopup=function(e){i();var t,n,r,o=l(this);return"string"==typeof e?"open"===e?(t=s?o.data("magnificPopup"):o[0].magnificPopup,n=parseInt(arguments[1],10)||0,r=t.items?t.items[n]:(r=o,(r=t.delegate?o.find(t.delegate):r).eq(n)),h._openClick({mfpEl:r},o,t)):h.isOpen&&h[e].apply(h,Array.prototype.slice.call(arguments,1)):(e=l.extend(!0,{},e),s?o.data("magnificPopup",e):o[0].magnificPopup=e,h.addGroup(o,e)),o};function T(){k&&(S.after(k.addClass(E)).detach(),k=null)}var E,S,k,A="inline";l.magnificPopup.registerModule(A,{options:{hiddenClass:"hide",markup:"",tNotFound:"Content not found"},proto:{initInline:function(){h.types.push(A),c(u+"."+A,function(){T()})},getInline:function(e,t){if(T(),e.src){var n,r=h.st.inline,o=l(e.src);return o.length?((n=o[0].parentNode)&&n.tagName&&(S||(E=r.hiddenClass,S=f(E),E="mfp-"+E),k=o.after(S).detach().removeClass(E)),h.updateStatus("ready")):(h.updateStatus("error",r.tNotFound),o=l("
")),e.inlineElement=o}return h.updateStatus("ready"),h._parseMarkup(t,{},e),t}}});function N(){I&&l(document.body).removeClass(I)}function j(){N(),h.req&&h.req.abort()}var I,L="ajax";l.magnificPopup.registerModule(L,{options:{settings:null,cursor:"mfp-ajax-cur",tError:'The content could not be loaded.'},proto:{initAjax:function(){h.types.push(L),I=h.st.ajax.cursor,c(u+"."+L,j),c("BeforeChange."+L,j)},getAjax:function(r){I&&l(document.body).addClass(I),h.updateStatus("loading");var e=l.extend({url:r.src,success:function(e,t,n){n={data:e,xhr:n};d("ParseAjax",n),h.appendContent(l(n.data),L),r.finished=!0,N(),h._setFocus(),setTimeout(function(){h.wrap.addClass(w)},16),h.updateStatus("ready"),d("AjaxContentAdded")},error:function(){N(),r.finished=r.loadError=!0,h.updateStatus("error",h.st.ajax.tError.replace("%url%",r.src))}},h.st.ajax.settings);return h.req=l.ajax(e),""}}});var D;l.magnificPopup.registerModule("image",{options:{markup:'
',cursor:"mfp-zoom-out-cur",titleSrc:"title",verticalFit:!0,tError:'The image could not be loaded.'},proto:{initImage:function(){var e=h.st.image,t=".image";h.types.push("image"),c(b+t,function(){"image"===h.currItem.type&&e.cursor&&l(document.body).addClass(e.cursor)}),c(u+t,function(){e.cursor&&l(document.body).removeClass(e.cursor),C.off("resize"+x)}),c("Resize"+t,h.resizeImage),h.isLowIE&&c("AfterChange",h.resizeImage)},resizeImage:function(){var e,t=h.currItem;t&&t.img&&h.st.image.verticalFit&&(e=0,h.isLowIE&&(e=parseInt(t.img.css("padding-top"),10)+parseInt(t.img.css("padding-bottom"),10)),t.img.css("max-height",h.wH-e))},_onImageHasSize:function(e){e.img&&(e.hasSize=!0,D&&clearInterval(D),e.isCheckingImgSize=!1,d("ImageHasSize",e),e.imgHidden&&(h.content&&h.content.removeClass("mfp-loading"),e.imgHidden=!1))},findImageSize:function(t){var n=0,r=t.img[0],o=function(e){D&&clearInterval(D),D=setInterval(function(){0
',srcAction:"iframe_src",patterns:{youtube:{index:"youtube.com",id:"v=",src:"//www.youtube.com/embed/%id%?autoplay=1"},vimeo:{index:"vimeo.com/",id:"/",src:"//player.vimeo.com/video/%id%?autoplay=1"},gmaps:{index:"//maps.google.",src:"%id%&output=embed"}}},proto:{initIframe:function(){h.types.push(P),c("BeforeChange",function(e,t,n){t!==n&&(t===P?H():n===P&&H(!0))}),c(u+"."+P,function(){H()})},getIframe:function(e,t){var n=e.src,r=h.st.iframe;l.each(r.patterns,function(){if(-1',preload:[0,2],navigateByImgClick:!0,arrows:!0,tPrev:"Previous (Left arrow key)",tNext:"Next (Right arrow key)",tCounter:"%curr% of %total%"},proto:{initGallery:function(){var i=h.st.gallery,e=".mfp-gallery";if(h.direction=!0,!i||!i.enabled)return!1;g+=" mfp-gallery",c(b+e,function(){i.navigateByImgClick&&h.wrap.on("click"+e,".mfp-img",function(){if(1=h.index,h.index=e,h.updateItemHTML()},preloadNearbyImages:function(){for(var e=h.st.gallery.preload,t=Math.min(e[0],h.items.length),n=Math.min(e[1],h.items.length),r=1;r<=(h.direction?n:t);r++)h._preloadItem(h.index+r);for(r=1;r<=(h.direction?t:n);r++)h._preloadItem(h.index-r)},_preloadItem:function(e){var t;e=q(e),h.items[e].preloaded||((t=h.items[e]).parsed||(t=h.parseEl(e)),d("LazyLoad",t),"image"===t.type&&(t.img=l('').on("load.mfploader",function(){t.hasSize=!0}).on("error.mfploader",function(){t.hasSize=!0,t.loadError=!0,d("LazyLoadError",t)}).attr("src",t.src)),t.preloaded=!0)}}});var _="retina";l.magnificPopup.registerModule(_,{options:{replaceSrc:function(e){return e.src.replace(/\.\w+$/,function(e){return"@2x"+e})},ratio:1},proto:{initRetina:function(){var n,r;1t.durationMax?t.durationMax:t.durationMin&&e=u)return b.cancelScroll(!0),e=t,n=g,0===(t=r)&&document.body.focus(),n||(t.focus(),document.activeElement!==t&&(t.setAttribute("tabindex","-1"),t.focus(),t.style.outline="none"),x.scrollTo(0,e)),E("scrollStop",m,r,o),!(y=f=null)},h=function(e){var t,n,r;l+=e-(f=f||e),d=i+s*(n=d=1<(d=0===c?0:l/c)?1:d,"easeInQuad"===(t=m).easing&&(r=n*n),"easeOutQuad"===t.easing&&(r=n*(2-n)),"easeInOutQuad"===t.easing&&(r=n<.5?2*n*n:(4-2*n)*n-1),"easeInCubic"===t.easing&&(r=n*n*n),"easeOutCubic"===t.easing&&(r=--n*n*n+1),"easeInOutCubic"===t.easing&&(r=n<.5?4*n*n*n:(n-1)*(2*n-2)*(2*n-2)+1),"easeInQuart"===t.easing&&(r=n*n*n*n),"easeOutQuart"===t.easing&&(r=1- --n*n*n*n),"easeInOutQuart"===t.easing&&(r=n<.5?8*n*n*n*n:1-8*--n*n*n*n),"easeInQuint"===t.easing&&(r=n*n*n*n*n),"easeOutQuint"===t.easing&&(r=1+--n*n*n*n*n),"easeInOutQuint"===t.easing&&(r=n<.5?16*n*n*n*n*n:1+16*--n*n*n*n*n),(r=t.customEasing?t.customEasing(n):r)||n),x.scrollTo(0,Math.floor(d)),p(d,a)||(y=x.requestAnimationFrame(h),f=e)},0===x.pageYOffset&&x.scrollTo(0,0),t=r,e=m,g||history.pushState&&e.updateURL&&history.pushState({smoothScroll:JSON.stringify(e),anchor:t.id},document.title,t===document.documentElement?"#top":"#"+t.id),"matchMedia"in x&&x.matchMedia("(prefers-reduced-motion)").matches?x.scrollTo(0,Math.floor(a)):(E("scrollStart",m,r,o),b.cancelScroll(!0),x.requestAnimationFrame(h)))};function t(e){if(!e.defaultPrevented&&!(0!==e.button||e.metaKey||e.ctrlKey||e.shiftKey)&&"closest"in e.target&&(o=e.target.closest(r))&&"a"===o.tagName.toLowerCase()&&!e.target.closest(v.ignore)&&o.hostname===x.location.hostname&&o.pathname===x.location.pathname&&/#/.test(o.href)){var t,n;try{n=a(decodeURIComponent(o.hash))}catch(e){n=a(o.hash)}if("#"===n){if(!v.topOnEmptyHash)return;t=document.documentElement}else t=document.querySelector(n);(t=t||"#top"!==n?t:document.documentElement)&&(e.preventDefault(),n=v,history.replaceState&&n.updateURL&&!history.state&&(e=(e=x.location.hash)||"",history.replaceState({smoothScroll:JSON.stringify(n),anchor:e||x.pageYOffset},document.title,e||x.location.href)),b.animateScroll(t,o))}}function i(e){var t;null!==history.state&&history.state.smoothScroll&&history.state.smoothScroll===JSON.stringify(v)&&("string"==typeof(t=history.state.anchor)&&t&&!(t=document.querySelector(a(history.state.anchor)))||b.animateScroll(t,null,{updateURL:!1}))}b.destroy=function(){v&&(document.removeEventListener("click",t,!1),x.removeEventListener("popstate",i,!1),b.cancelScroll(),y=n=o=v=null)};return function(){if(!("querySelector"in document&&"addEventListener"in x&&"requestAnimationFrame"in x&&"closest"in x.Element.prototype))throw"Smooth Scroll: This browser does not support the required JavaScript methods and browser APIs.";b.destroy(),v=w(S,e||{}),n=v.header?document.querySelector(v.header):null,document.addEventListener("click",t,!1),v.updateURL&&v.popstate&&x.addEventListener("popstate",i,!1)}(),b}}),function(e,t){"function"==typeof define&&define.amd?define([],function(){return t(e)}):"object"==typeof exports?module.exports=t(e):e.Gumshoe=t(e)}("undefined"!=typeof global?global:"undefined"!=typeof window?window:this,function(c){"use strict";function f(e,t,n){n.settings.events&&(n=new CustomEvent(e,{bubbles:!0,cancelable:!0,detail:n}),t.dispatchEvent(n))}function n(e){var t=0;if(e.offsetParent)for(;e;)t+=e.offsetTop,e=e.offsetParent;return 0<=t?t:0}function d(e){e&&e.sort(function(e,t){return n(e.content)=Math.max(document.body.scrollHeight,document.documentElement.scrollHeight,document.body.offsetHeight,document.documentElement.offsetHeight,document.body.clientHeight,document.documentElement.clientHeight)}function p(e,t){var n,r,o=e[e.length-1];if(n=o,r=t,!(!s()||!a(n.content,r,!0)))return o;for(var i=e.length-1;0<=i;i--)if(a(e[i].content,t))return e[i]}function h(e,t){var n;!e||(n=e.nav.closest("li"))&&(n.classList.remove(t.navClass),e.content.classList.remove(t.contentClass),r(n,t),f("gumshoeDeactivate",n,{link:e.nav,content:e.content,settings:t}))}var m={navClass:"active",contentClass:"active",nested:!1,nestedClass:"active",offset:0,reflow:!1,events:!0},r=function(e,t){!t.nested||(e=e.parentNode.closest("li"))&&(e.classList.remove(t.nestedClass),r(e,t))},g=function(e,t){!t.nested||(e=e.parentNode.closest("li"))&&(e.classList.add(t.nestedClass),g(e,t))};return function(e,t){var n,o,i,r,a,s={setup:function(){n=document.querySelectorAll(e),o=[],Array.prototype.forEach.call(n,function(e){var t=document.getElementById(decodeURIComponent(e.hash.substr(1)));t&&o.push({nav:e,content:t})}),d(o)}};s.detect=function(){var e,t,n,r=p(o,a);r?i&&r.content===i.content||(h(i,a),t=a,!(e=r)||(n=e.nav.closest("li"))&&(n.classList.add(t.navClass),e.content.classList.add(t.contentClass),g(n,t),f("gumshoeActivate",n,{link:e.nav,content:e.content,settings:t})),i=r):i&&(h(i,a),i=null)};function u(e){r&&c.cancelAnimationFrame(r),r=c.requestAnimationFrame(s.detect)}function l(e){r&&c.cancelAnimationFrame(r),r=c.requestAnimationFrame(function(){d(o),s.detect()})}s.destroy=function(){i&&h(i,a),c.removeEventListener("scroll",u,!1),a.reflow&&c.removeEventListener("resize",l,!1),a=r=i=n=o=null};return a=function(){var n={};return Array.prototype.forEach.call(arguments,function(e){for(var t in e){if(!e.hasOwnProperty(t))return;n[t]=e[t]}}),n}(m,t||{}),s.setup(),s.detect(),c.addEventListener("scroll",u,!1),a.reflow&&c.addEventListener("resize",l,!1),s}}),$(document).ready(function(){$("#main").fitVids();function e(){(0===$(".author__urls-wrapper button").length?1024<$(window).width():!$(".author__urls-wrapper button").is(":visible"))?$(".sidebar").addClass("sticky"):$(".sidebar").removeClass("sticky")}e(),$(window).resize(function(){e()}),$(".author__urls-wrapper button").on("click",function(){$(".author__urls").toggleClass("is--visible"),$(".author__urls-wrapper button").toggleClass("open")}),$(document).keyup(function(e){27===e.keyCode&&$(".initial-content").hasClass("is--hidden")&&($(".search-content").toggleClass("is--visible"),$(".initial-content").toggleClass("is--hidden"))}),$(".search__toggle").on("click",function(){$(".search-content").toggleClass("is--visible"),$(".initial-content").toggleClass("is--hidden"),setTimeout(function(){$(".search-content input").focus()},400)});new SmoothScroll('a[href*="#"]',{offset:20,speed:400,speedAsDuration:!0,durationMax:500});0<$("nav.toc").length&&new Gumshoe("nav.toc a",{navClass:"active",contentClass:"active",nested:!1,nestedClass:"active",offset:20,reflow:!0,events:!0}),$("a[href$='.jpg'],a[href$='.jpeg'],a[href$='.JPG'],a[href$='.png'],a[href$='.gif'],a[href$='.webp']").addClass("image-popup"),$(".image-popup").magnificPopup({type:"image",tLoading:"Loading image #%curr%...",gallery:{enabled:!0,navigateByImgClick:!0,preload:[0,1]},image:{tError:'Image #%curr% could not be loaded.'},removalDelay:500,mainClass:"mfp-zoom-in",callbacks:{beforeOpen:function(){this.st.image.markup=this.st.image.markup.replace("mfp-figure","mfp-figure mfp-with-anim")}},closeOnContentClick:!0,midClick:!0}),$(".page__content").find("h1, h2, h3, h4, h5, h6").each(function(){var e,t=$(this).attr("id");t&&((e=document.createElement("a")).className="header-link",e.href="#"+t,e.innerHTML='Permalink',e.title="Permalink",$(this).append(e))})}); \ No newline at end of file diff --git a/assets/js/plugins/bigfoot.min.js b/assets/js/plugins/bigfoot.min.js new file mode 100644 index 000000000..35d201cea --- /dev/null +++ b/assets/js/plugins/bigfoot.min.js @@ -0,0 +1,39 @@ +(function(){(function($){return $.bigfoot=function(options){var addBreakpoint,baseFontSize,bigfoot,buttonHover,calculatePixelDimension,cleanFootnoteLinks,clickButton,createPopover,defaults,deleteEmptyOrHR,escapeKeypress,footnoteInit,getSetting,makeDefaultCallbacks,popoverStates,positionTooltip,removeBackLinks,removeBreakpoint,removePopovers,replaceWithReferenceAttributes,repositionFeet,roomCalc,settings,touchClick,unhoverFeet,updateSetting,viewportDetails;bigfoot=void 0;defaults={actionOriginalFN:"hide",activateCallback:function(){},activateOnHover:!1,allowMultipleFN:!1,anchorPattern:/(fn|footnote|note)[:\-_\d]/gi,anchorParentTagname:'sup',breakpoints:{},deleteOnUnhover:!1,footnoteParentClass:'footnote',footnoteTagname:'li',hoverDelay:250,numberResetSelector:void 0,popoverDeleteDelay:300,popoverCreateDelay:100,positionContent:!0,preventPageScroll:!0,scope:!1,useFootnoteOnlyOnce:!0,contentMarkup:"",buttonMarkup:"
"};settings=$.extend(defaults,options);popoverStates={};footnoteInit=function(){var $curResetElement,$currentLastFootnoteLink,$footnoteAnchors,$footnoteButton,$lastResetElement,$parent,$relevantFNLink,$relevantFootnote,finalFNLinks,footnoteButton,footnoteButtonSearchQuery,footnoteContent,footnoteIDNum,footnoteLinks,footnoteNum,footnotes,i,_i,_ref,_results;footnoteButtonSearchQuery=settings.scope?""+settings.scope+" a[href*='#']":"a[href*='#']";$footnoteAnchors=$(footnoteButtonSearchQuery).filter(function(){var $this,relAttr;$this=$(this);relAttr=$this.attr("rel");if(relAttr==="null"||(relAttr==null)){relAttr=""} +return(""+($this.attr("href"))+relAttr).match(settings.anchorPattern)&&$this.closest("[class*="+settings.footnoteParentClass+"]:not(a):not("+settings.anchorParentTagname+")").length<1});footnotes=[];footnoteLinks=[];finalFNLinks=[];cleanFootnoteLinks($footnoteAnchors,footnoteLinks);$(footnoteLinks).each(function(){var $closestFootnoteEl,relatedFN;relatedFN=$(this).data("footnote-ref").replace(/[:.+~*\]\[]/g,"\\$&");if(settings.useFootnoteOnlyOnce){relatedFN=""+relatedFN+":not(.footnote-processed)"} +$closestFootnoteEl=$(relatedFN).closest(settings.footnoteTagname);if($closestFootnoteEl.length>0){footnotes.push($closestFootnoteEl.first().addClass("footnote-processed"));return finalFNLinks.push(this)}});$currentLastFootnoteLink=$("[data-footnote-identifier]:last");footnoteIDNum=$currentLastFootnoteLink.length<1?0:+$currentLastFootnoteLink.data("footnote-identifier");_results=[];for(i=_i=0,_ref=footnotes.length;0<=_ref?_i<_ref:_i>_ref;i=0<=_ref?++_i:--_i){footnoteContent=removeBackLinks($(footnotes[i]).html().trim(),$(finalFNLinks[i]).data("footnote-backlink-ref"));footnoteContent=footnoteContent.replace(/"/g,""").replace(/</g,"<sym;").replace(/>/g,">sym;").replace(/'/g,"'");footnoteIDNum+=1;footnoteButton="";$relevantFNLink=$(finalFNLinks[i]);$relevantFootnote=$(footnotes[i]);if(settings.numberResetSelector!=null){$curResetElement=$relevantFNLink.closest(settings.numberResetSelector);if($curResetElement.is($lastResetElement)){footnoteNum+=1}else{footnoteNum=1} +$lastResetElement=$curResetElement}else{footnoteNum=footnoteIDNum} +if(footnoteContent.indexOf("<")!==0){footnoteContent="

"+footnoteContent+"

"} +footnoteButton=settings.buttonMarkup.replace(/\{\{FOOTNOTENUM\}\}/g,footnoteNum).replace(/\{\{FOOTNOTEID\}\}/g,footnoteIDNum).replace(/\{\{FOOTNOTECONTENT\}\}/g,footnoteContent);footnoteButton=replaceWithReferenceAttributes(footnoteButton,"SUP",$relevantFNLink);footnoteButton=replaceWithReferenceAttributes(footnoteButton,"FN",$relevantFootnote);$footnoteButton=$(footnoteButton).insertBefore($relevantFNLink);$parent=$relevantFootnote.parent();switch(settings.actionOriginalFN.toLowerCase()){case "hide":$relevantFNLink.addClass("footnote-print-only");$relevantFootnote.addClass("footnote-print-only");_results.push(deleteEmptyOrHR($parent));break;case "delete":$relevantFNLink.remove();$relevantFootnote.remove();_results.push(deleteEmptyOrHR($parent));break;default:_results.push($relevantFNLink.addClass("footnote-print-only"))}} +return _results};cleanFootnoteLinks=function($footnoteAnchors,footnoteLinks){var $parent,$supChild,linkHREF,linkID;if(footnoteLinks==null){footnoteLinks=[]} +$parent=void 0;$supChild=void 0;linkHREF=void 0;linkID=void 0;$footnoteAnchors.each(function(){var $child,$this;$this=$(this);linkHREF="#"+($this.attr("href")).split("#")[1];$parent=$this.closest(settings.anchorParentTagname);$child=$this.find(settings.anchorParentTagname);if($parent.length>0){linkID=($parent.attr("id")||"")+($this.attr("id")||"");return footnoteLinks.push($parent.attr({"data-footnote-backlink-ref":linkID,"data-footnote-ref":linkHREF}))}else if($child.length>0){linkID=($child.attr("id")||"")+($this.attr("id")||"");return footnoteLinks.push($this.attr({"data-footnote-backlink-ref":linkID,"data-footnote-ref":linkHREF}))}else{linkID=$this.attr("id")||"";return footnoteLinks.push($this.attr({"data-footnote-backlink-ref":linkID,"data-footnote-ref":linkHREF}))}})};deleteEmptyOrHR=function($el){var $parent;$parent=void 0;if($el.is(":empty")||$el.children(":not(.footnote-print-only)").length===0){$parent=$el.parent();if(settings.actionOriginalFN.toLowerCase()==="delete"){$el.remove()}else{$el.addClass("footnote-print-only")} +return deleteEmptyOrHR($parent)}else if($el.children(":not(.footnote-print-only)").length===$el.children("hr:not(.footnote-print-only)").length){$parent=$el.parent();if(settings.actionOriginalFN.toLowerCase()==="delete"){$el.remove()}else{$el.children("hr").addClass("footnote-print-only");$el.addClass("footnote-print-only")} +return deleteEmptyOrHR($parent)}};removeBackLinks=function(footnoteHTML,backlinkID){var regex;if(backlinkID.indexOf(' ')>=0){backlinkID=backlinkID.trim().replace(/\s+/g,"|").replace(/(.*)/g,"($1)")} +regex=new RegExp("(\\s| )*<\\s*a[^#<]*#"+backlinkID+"[^>]*>(.*?)<\\s*/\\s*a>","g");return footnoteHTML.replace(regex,"").replace("[]","")};replaceWithReferenceAttributes=function(string,referenceKeyword,$referenceElement){var refMatches,refRegex,refReplaceRegex,refReplaceText;refRegex=new RegExp("\\{\\{"+referenceKeyword+":([^\\}]*)\\}\\}","g");refMatches=void 0;refReplaceText=void 0;refReplaceRegex=void 0;refMatches=refRegex.exec(string);while(refMatches){if(refMatches[1]){refReplaceText=$referenceElement.attr(refMatches[1])||"";string=string.replace("{{"+referenceKeyword+":"+refMatches[1]+"}}",refReplaceText)} +refMatches=refRegex.exec(string)} +return string};buttonHover=function(event){var $buttonHovered,dataIdentifier,otherPopoverSelector;if(settings.activateOnHover){$buttonHovered=$(event.target).closest(".bigfoot-footnote__button");dataIdentifier="[data-footnote-identifier='"+($buttonHovered.attr("data-footnote-identifier"))+"']";if($buttonHovered.hasClass("is-active")){return} +$buttonHovered.addClass("is-hover-instantiated");if(!settings.allowMultipleFN){otherPopoverSelector=".bigfoot-footnote:not("+dataIdentifier+")";removePopovers(otherPopoverSelector)} +createPopover(".bigfoot-footnote__button"+dataIdentifier).addClass("is-hover-instantiated")}};touchClick=function(event){var $nearButton,$nearFootnote,$target;$target=$(event.target);$nearButton=$target.closest(".bigfoot-footnote__button");$nearFootnote=$target.closest(".bigfoot-footnote");if($nearButton.length>0){event.preventDefault();clickButton($nearButton)}else if($nearFootnote.length<1){if($(".bigfoot-footnote").length>0){removePopovers()}}};clickButton=function($button){var dataIdentifier;$button.blur();dataIdentifier="data-footnote-identifier='"+($button.attr("data-footnote-identifier"))+"'";if($button.hasClass("changing")){return}else if(!$button.hasClass("is-active")){$button.addClass("changing");setTimeout((function(){return $button.removeClass("changing")}),settings.popoverCreateDelay);createPopover(".bigfoot-footnote__button["+dataIdentifier+"]");$button.addClass("is-click-instantiated");if(!settings.allowMultipleFN){removePopovers(".bigfoot-footnote:not(["+dataIdentifier+"])")}}else{if(!settings.allowMultipleFN){removePopovers()}else{removePopovers(".bigfoot-footnote["+dataIdentifier+"]")}}};createPopover=function(selector){var $buttons,$popoversCreated;$buttons=void 0;if(typeof selector!=="string"&&settings.allowMultipleFN){$buttons=selector}else if(typeof selector!=="string"){$buttons=selector.first()}else if(settings.allowMultipleFN){$buttons=$(selector).closest(".bigfoot-footnote__button")}else{$buttons=$(selector+":first").closest(".bigfoot-footnote__button")} +$popoversCreated=$();$buttons.each(function(){var $content,$contentContainer,$this,content;$this=$(this);content=void 0;try{content=settings.contentMarkup.replace(/\{\{FOOTNOTENUM\}\}/g,$this.attr("data-footnote-number")).replace(/\{\{FOOTNOTEID\}\}/g,$this.attr("data-footnote-identifier")).replace(/\{\{FOOTNOTECONTENT\}\}/g,$this.attr("data-bigfoot-footnote")).replace(/\>sym\;/g,">").replace(/\<sym\;/g,"<");return content=replaceWithReferenceAttributes(content,"BUTTON",$this)}finally{$content=$(content);try{settings.activateCallback($content,$this)}catch(_error){} +$content.insertAfter($buttons);popoverStates[$this.attr("data-footnote-identifier")]="init";$content.attr("bigfoot-max-width",calculatePixelDimension($content.css("max-width"),$content));$content.css("max-width",10000);$contentContainer=$content.find(".bigfoot-footnote__content");$content.attr("data-bigfoot-max-height",calculatePixelDimension($contentContainer.css("max-height"),$contentContainer));repositionFeet();$this.addClass("is-active");$content.find(".bigfoot-footnote__content").bindScrollHandler();$popoversCreated=$popoversCreated.add($content)}});setTimeout((function(){return $popoversCreated.addClass("is-active")}),settings.popoverCreateDelay);return $popoversCreated};baseFontSize=function(){var el,size;el=document.createElement("div");el.style.cssText="display:inline-block;padding:0;line-height:1;position:absolute;visibility:hidden;font-size:1em;";el.appendChild(document.createElement("M"));document.body.appendChild(el);size=el.offsetHeight;document.body.removeChild(el);return size};calculatePixelDimension=function(dim,$el){if(dim==="none"){dim=10000}else if(dim.indexOf("rem")>=0){dim=parseFloat(dim)*baseFontSize()}else if(dim.indexOf("em")>=0){dim=parseFloat(dim)*parseFloat($el.css("font-size"))}else if(dim.indexOf("px")>=0){dim=parseFloat(dim);if(dim<=60){dim=dim/parseFloat($el.parent().css("width"))}}else if(dim.indexOf("%")>=0){dim=parseFloat(dim)/100} +return dim};$.fn.bindScrollHandler=function(){if(!settings.preventPageScroll){return $(this)} +$(this).on("DOMMouseScroll mousewheel",function(event){var $popover,$this,delta,height,prevent,scrollHeight,scrollTop,up;$this=$(this);scrollTop=$this.scrollTop();scrollHeight=$this[0].scrollHeight;height=parseInt($this.css("height"));$popover=$this.closest(".bigfoot-footnote");if($this.scrollTop()>0&&$this.scrollTop()<10){$popover.addClass("is-scrollable")} +if(!$popover.hasClass("is-scrollable")){return} +delta=event.type==="DOMMouseScroll"?event.originalEvent.detail*-40:event.originalEvent.wheelDelta;up=delta>0;prevent=function(){event.stopPropagation();event.preventDefault();event.returnValue=!1;return!1};if(!up&&-delta>scrollHeight-height-scrollTop){$this.scrollTop(scrollHeight);$popover.addClass("is-fully-scrolled");return prevent()}else if(up&&delta>scrollTop){$this.scrollTop(0);$popover.removeClass("is-fully-scrolled");return prevent()}else{return $popover.removeClass("is-fully-scrolled")}});return $(this)};unhoverFeet=function(e){if(settings.deleteOnUnhover&&settings.activateOnHover){return setTimeout((function(){var $target;$target=$(e.target).closest(".bigfoot-footnote, .bigfoot-footnote__button");if($(".bigfoot-footnote__button:hover, .bigfoot-footnote:hover").length<1){return removePopovers()}}),settings.hoverDelay)}};escapeKeypress=function(event){if(event.keyCode===27){return removePopovers()}};removePopovers=function(footnotes,timeout){var $buttonsClosed,$linkedButton,$this,footnoteID;if(footnotes==null){footnotes=".bigfoot-footnote"} +if(timeout==null){timeout=settings.popoverDeleteDelay} +$buttonsClosed=$();footnoteID=void 0;$linkedButton=void 0;$this=void 0;$(footnotes).each(function(){$this=$(this);footnoteID=$this.attr("data-footnote-identifier");$linkedButton=$(".bigfoot-footnote__button[data-footnote-identifier='"+footnoteID+"']");if(!$linkedButton.hasClass("changing")){$buttonsClosed=$buttonsClosed.add($linkedButton);$linkedButton.removeClass("is-active is-hover-instantiated is-click-instantiated").addClass("changing");$this.removeClass("is-active").addClass("disapearing");return setTimeout((function(){$this.remove();delete popoverStates[footnoteID];return $linkedButton.removeClass("changing")}),timeout)}});return $buttonsClosed};repositionFeet=function(e){var type;if(settings.positionContent){type=e?e.type:"resize";$(".bigfoot-footnote").each(function(){var $button,$contentWrapper,$mainWrap,$this,dataIdentifier,identifier,lastState,marginSize,maxHeightInCSS,maxHeightOnScreen,maxWidth,maxWidthInCSS,positionOnTop,relativeToWidth,roomLeft,totalHeight;$this=$(this);identifier=$this.attr("data-footnote-identifier");dataIdentifier="data-footnote-identifier='"+identifier+"'";$contentWrapper=$this.find(".bigfoot-footnote__content");$button=$this.siblings(".bigfoot-footnote__button");roomLeft=roomCalc($button);marginSize=parseFloat($this.css("margin-top"));maxHeightInCSS=+($this.attr("data-bigfoot-max-height"));totalHeight=2*marginSize+$this.outerHeight();maxHeightOnScreen=10000;positionOnTop=roomLeft.bottomRoomroomLeft.bottomRoom;lastState=popoverStates[identifier];if(positionOnTop){if(lastState!=="top"){popoverStates[identifier]="top";$this.addClass("is-positioned-top").removeClass("is-positioned-bottom");$this.css("transform-origin",(roomLeft.leftRelative*100)+"% 100%")} +maxHeightOnScreen=roomLeft.topRoom-marginSize-15}else{if(lastState!=="bottom"||lastState==="init"){popoverStates[identifier]="bottom";$this.removeClass("is-positioned-top").addClass("is-positioned-bottom");$this.css("transform-origin",(roomLeft.leftRelative*100)+"% 0%")} +maxHeightOnScreen=roomLeft.bottomRoom-marginSize-15} +$this.find(".bigfoot-footnote__content").css({"max-height":Math.min(maxHeightOnScreen,maxHeightInCSS)+"px"});if(type==="resize"){maxWidthInCSS=parseFloat($this.attr("bigfoot-max-width"));$mainWrap=$this.find(".bigfoot-footnote__wrapper");maxWidth=maxWidthInCSS;if(maxWidthInCSS<=1){relativeToWidth=(function(){var jq,userSpecifiedRelativeElWidth;userSpecifiedRelativeElWidth=10000;if(settings.maxWidthRelativeTo){jq=$(settings.maxWidthRelativeTo);if(jq.length>0){userSpecifiedRelativeElWidth=jq.outerWidth()}} +return Math.min(window.innerWidth,userSpecifiedRelativeElWidth)})();maxWidth=relativeToWidth*maxWidthInCSS} +maxWidth=Math.min(maxWidth,$this.find(".bigfoot-footnote__content").outerWidth()+1);$mainWrap.css("max-width",maxWidth+"px");$this.css({left:(-roomLeft.leftRelative*maxWidth+parseFloat($button.css("margin-left"))+$button.outerWidth()/2)+"px"});positionTooltip($this,roomLeft.leftRelative)} +if(parseInt($this.outerHeight())<$this.find(".bigfoot-footnote__content")[0].scrollHeight){return $this.addClass("is-scrollable")}})}};positionTooltip=function($popover,leftRelative){var $tooltip;if(leftRelative==null){leftRelative=0.5} +$tooltip=$popover.find(".bigfoot-footnote__tooltip");if($tooltip.length>0){$tooltip.css("left",""+(leftRelative*100)+"%")}};roomCalc=function($el){var elHeight,elLeftMargin,elWidth,leftRoom,topRoom,w;elLeftMargin=parseFloat($el.css("margin-left"));elWidth=parseFloat($el.outerWidth())-elLeftMargin;elHeight=parseFloat($el.outerHeight());w=viewportDetails();topRoom=$el.offset().top-w.scrollY+elHeight/2;leftRoom=$el.offset().left-w.scrollX+elWidth/2;return{topRoom:topRoom,bottomRoom:w.height-topRoom,leftRoom:leftRoom,rightRoom:w.width-leftRoom,leftRelative:leftRoom/w.width,topRelative:topRoom/w.height}};viewportDetails=function(){var $window;$window=$(window);return{width:window.innerWidth,height:window.innerHeight,scrollX:$window.scrollLeft(),scrollY:$window.scrollTop()}};addBreakpoint=function(size,trueCallback,falseCallback,deleteDelay,removeOpen){var falseDefaultPositionSetting,minMax,mqListener,mql,query,s,trueDefaultPositionSetting;if(deleteDelay==null){deleteDelay=settings.popoverDeleteDelay} +if(removeOpen==null){removeOpen=!0} +mql=void 0;minMax=void 0;s=void 0;if(typeof size==="string"){s=size.toLowerCase()==="iphone"?"<320px":size.toLowerCase()==="ipad"?"<768px":size;minMax=s.charAt(0)===">"?"min":s.charAt(0)==="<"?"max":null;query=minMax?"("+minMax+"-width: "+(s.substring(1))+")":s;mql=window.matchMedia(query)}else{mql=size} +if(mql.media&&mql.media==="invalid"){return{added:!1,mq:mql,listener:null}} +trueDefaultPositionSetting=minMax==="min";falseDefaultPositionSetting=minMax==="max";trueCallback=trueCallback||makeDefaultCallbacks(removeOpen,deleteDelay,trueDefaultPositionSetting,function($popover){return $popover.addClass("is-bottom-fixed")});falseCallback=falseCallback||makeDefaultCallbacks(removeOpen,deleteDelay,falseDefaultPositionSetting,function(){});mqListener=function(mq){if(mq.matches){trueCallback(removeOpen,bigfoot)}else{falseCallback(removeOpen,bigfoot)}};mql.addListener(mqListener);mqListener(mql);settings.breakpoints[size]={added:!0,mq:mql,listener:mqListener};return settings.breakpoints[size]};makeDefaultCallbacks=function(removeOpen,deleteDelay,position,callback){return function(removeOpen,bigfoot){var $closedPopovers;$closedPopovers=void 0;if(removeOpen){$closedPopovers=bigfoot.close();bigfoot.updateSetting("activateCallback",callback)} +return setTimeout((function(){bigfoot.updateSetting("positionContent",position);if(removeOpen){return bigfoot.activate($closedPopovers)}}),deleteDelay)}};removeBreakpoint=function(target,callback){var b,breakpoint,mq,mqFound;mq=null;b=void 0;mqFound=!1;if(typeof target==="string"){mqFound=settings.breakpoints[target]!==undefined}else{for(b in settings.breakpoints){if(settings.breakpoints.hasOwnProperty(b)&&settings.breakpoints[b].mq===target){mqFound=!0}}} +if(mqFound){breakpoint=settings.breakpoints[b||target];if(callback){callback({matches:!1})}else{breakpoint.listener({matches:!1})} +breakpoint.mq.removeListener(breakpoint.listener);delete settings.breakpoints[b||target]} +return mqFound};updateSetting=function(newSettings,value){var oldValue,prop;oldValue=void 0;if(typeof newSettings==="string"){oldValue=settings[newSettings];settings[newSettings]=value}else{oldValue={};for(prop in newSettings){if(newSettings.hasOwnProperty(prop)){oldValue[prop]=settings[prop];settings[prop]=newSettings[prop]}}} +return oldValue};getSetting=function(setting){return settings[setting]};$(document).ready(function(){footnoteInit();$(document).on("mouseenter",".bigfoot-footnote__button",buttonHover);$(document).on("touchend click",touchClick);$(document).on("mouseout",".is-hover-instantiated",unhoverFeet);$(document).on("keyup",escapeKeypress);$(window).on("scroll resize",repositionFeet);return $(document).on("gestureend",function(){return repositionFeet()})});bigfoot={removePopovers:removePopovers,close:removePopovers,createPopover:createPopover,activate:createPopover,repositionFeet:repositionFeet,reposition:repositionFeet,addBreakpoint:addBreakpoint,removeBreakpoint:removeBreakpoint,getSetting:getSetting,updateSetting:updateSetting};return bigfoot}})(jQuery)}).call(this) \ No newline at end of file diff --git a/assets/js/plugins/gumshoe.js b/assets/js/plugins/gumshoe.js new file mode 100644 index 000000000..713b6eb30 --- /dev/null +++ b/assets/js/plugins/gumshoe.js @@ -0,0 +1,484 @@ +/*! + * gumshoejs v5.1.1 + * A simple, framework-agnostic scrollspy script. + * (c) 2019 Chris Ferdinandi + * MIT License + * http://github.com/cferdinandi/gumshoe + */ + +(function (root, factory) { + if ( typeof define === 'function' && define.amd ) { + define([], (function () { + return factory(root); + })); + } else if ( typeof exports === 'object' ) { + module.exports = factory(root); + } else { + root.Gumshoe = factory(root); + } +})(typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : this, (function (window) { + + 'use strict'; + + // + // Defaults + // + + var defaults = { + + // Active classes + navClass: 'active', + contentClass: 'active', + + // Nested navigation + nested: false, + nestedClass: 'active', + + // Offset & reflow + offset: 0, + reflow: false, + + // Event support + events: true + + }; + + + // + // Methods + // + + /** + * Merge two or more objects together. + * @param {Object} objects The objects to merge together + * @returns {Object} Merged values of defaults and options + */ + var extend = function () { + var merged = {}; + Array.prototype.forEach.call(arguments, (function (obj) { + for (var key in obj) { + if (!obj.hasOwnProperty(key)) return; + merged[key] = obj[key]; + } + })); + return merged; + }; + + /** + * Emit a custom event + * @param {String} type The event type + * @param {Node} elem The element to attach the event to + * @param {Object} detail Any details to pass along with the event + */ + var emitEvent = function (type, elem, detail) { + + // Make sure events are enabled + if (!detail.settings.events) return; + + // Create a new event + var event = new CustomEvent(type, { + bubbles: true, + cancelable: true, + detail: detail + }); + + // Dispatch the event + elem.dispatchEvent(event); + + }; + + /** + * Get an element's distance from the top of the Document. + * @param {Node} elem The element + * @return {Number} Distance from the top in pixels + */ + var getOffsetTop = function (elem) { + var location = 0; + if (elem.offsetParent) { + while (elem) { + location += elem.offsetTop; + elem = elem.offsetParent; + } + } + return location >= 0 ? location : 0; + }; + + /** + * Sort content from first to last in the DOM + * @param {Array} contents The content areas + */ + var sortContents = function (contents) { + if(contents) { + contents.sort((function (item1, item2) { + var offset1 = getOffsetTop(item1.content); + var offset2 = getOffsetTop(item2.content); + if (offset1 < offset2) return -1; + return 1; + })); + } + }; + + /** + * Get the offset to use for calculating position + * @param {Object} settings The settings for this instantiation + * @return {Float} The number of pixels to offset the calculations + */ + var getOffset = function (settings) { + + // if the offset is a function run it + if (typeof settings.offset === 'function') { + return parseFloat(settings.offset()); + } + + // Otherwise, return it as-is + return parseFloat(settings.offset); + + }; + + /** + * Get the document element's height + * @private + * @returns {Number} + */ + var getDocumentHeight = function () { + return Math.max( + document.body.scrollHeight, document.documentElement.scrollHeight, + document.body.offsetHeight, document.documentElement.offsetHeight, + document.body.clientHeight, document.documentElement.clientHeight + ); + }; + + /** + * Determine if an element is in view + * @param {Node} elem The element + * @param {Object} settings The settings for this instantiation + * @param {Boolean} bottom If true, check if element is above bottom of viewport instead + * @return {Boolean} Returns true if element is in the viewport + */ + var isInView = function (elem, settings, bottom) { + var bounds = elem.getBoundingClientRect(); + var offset = getOffset(settings); + if (bottom) { + return parseInt(bounds.bottom, 10) < (window.innerHeight || document.documentElement.clientHeight); + } + return parseInt(bounds.top, 10) <= offset; + }; + + /** + * Check if at the bottom of the viewport + * @return {Boolean} If true, page is at the bottom of the viewport + */ + var isAtBottom = function () { + if (window.innerHeight + window.pageYOffset >= getDocumentHeight()) return true; + return false; + }; + + /** + * Check if the last item should be used (even if not at the top of the page) + * @param {Object} item The last item + * @param {Object} settings The settings for this instantiation + * @return {Boolean} If true, use the last item + */ + var useLastItem = function (item, settings) { + if (isAtBottom() && isInView(item.content, settings, true)) return true; + return false; + }; + + /** + * Get the active content + * @param {Array} contents The content areas + * @param {Object} settings The settings for this instantiation + * @return {Object} The content area and matching navigation link + */ + var getActive = function (contents, settings) { + var last = contents[contents.length-1]; + if (useLastItem(last, settings)) return last; + for (var i = contents.length - 1; i >= 0; i--) { + if (isInView(contents[i].content, settings)) return contents[i]; + } + }; + + /** + * Deactivate parent navs in a nested navigation + * @param {Node} nav The starting navigation element + * @param {Object} settings The settings for this instantiation + */ + var deactivateNested = function (nav, settings) { + + // If nesting isn't activated, bail + if (!settings.nested) return; + + // Get the parent navigation + var li = nav.parentNode.closest('li'); + if (!li) return; + + // Remove the active class + li.classList.remove(settings.nestedClass); + + // Apply recursively to any parent navigation elements + deactivateNested(li, settings); + + }; + + /** + * Deactivate a nav and content area + * @param {Object} items The nav item and content to deactivate + * @param {Object} settings The settings for this instantiation + */ + var deactivate = function (items, settings) { + + // Make sure their are items to deactivate + if (!items) return; + + // Get the parent list item + var li = items.nav.closest('li'); + if (!li) return; + + // Remove the active class from the nav and content + li.classList.remove(settings.navClass); + items.content.classList.remove(settings.contentClass); + + // Deactivate any parent navs in a nested navigation + deactivateNested(li, settings); + + // Emit a custom event + emitEvent('gumshoeDeactivate', li, { + link: items.nav, + content: items.content, + settings: settings + }); + + }; + + + /** + * Activate parent navs in a nested navigation + * @param {Node} nav The starting navigation element + * @param {Object} settings The settings for this instantiation + */ + var activateNested = function (nav, settings) { + + // If nesting isn't activated, bail + if (!settings.nested) return; + + // Get the parent navigation + var li = nav.parentNode.closest('li'); + if (!li) return; + + // Add the active class + li.classList.add(settings.nestedClass); + + // Apply recursively to any parent navigation elements + activateNested(li, settings); + + }; + + /** + * Activate a nav and content area + * @param {Object} items The nav item and content to activate + * @param {Object} settings The settings for this instantiation + */ + var activate = function (items, settings) { + + // Make sure their are items to activate + if (!items) return; + + // Get the parent list item + var li = items.nav.closest('li'); + if (!li) return; + + // Add the active class to the nav and content + li.classList.add(settings.navClass); + items.content.classList.add(settings.contentClass); + + // Activate any parent navs in a nested navigation + activateNested(li, settings); + + // Emit a custom event + emitEvent('gumshoeActivate', li, { + link: items.nav, + content: items.content, + settings: settings + }); + + }; + + /** + * Create the Constructor object + * @param {String} selector The selector to use for navigation items + * @param {Object} options User options and settings + */ + var Constructor = function (selector, options) { + + // + // Variables + // + + var publicAPIs = {}; + var navItems, contents, current, timeout, settings; + + + // + // Methods + // + + /** + * Set variables from DOM elements + */ + publicAPIs.setup = function () { + + // Get all nav items + navItems = document.querySelectorAll(selector); + + // Create contents array + contents = []; + + // Loop through each item, get it's matching content, and push to the array + Array.prototype.forEach.call(navItems, (function (item) { + + // Get the content for the nav item + var content = document.getElementById(decodeURIComponent(item.hash.substr(1))); + if (!content) return; + + // Push to the contents array + contents.push({ + nav: item, + content: content + }); + + })); + + // Sort contents by the order they appear in the DOM + sortContents(contents); + + }; + + /** + * Detect which content is currently active + */ + publicAPIs.detect = function () { + + // Get the active content + var active = getActive(contents, settings); + + // if there's no active content, deactivate and bail + if (!active) { + if (current) { + deactivate(current, settings); + current = null; + } + return; + } + + // If the active content is the one currently active, do nothing + if (current && active.content === current.content) return; + + // Deactivate the current content and activate the new content + deactivate(current, settings); + activate(active, settings); + + // Update the currently active content + current = active; + + }; + + /** + * Detect the active content on scroll + * Debounced for performance + */ + var scrollHandler = function (event) { + + // If there's a timer, cancel it + if (timeout) { + window.cancelAnimationFrame(timeout); + } + + // Setup debounce callback + timeout = window.requestAnimationFrame(publicAPIs.detect); + + }; + + /** + * Update content sorting on resize + * Debounced for performance + */ + var resizeHandler = function (event) { + + // If there's a timer, cancel it + if (timeout) { + window.cancelAnimationFrame(timeout); + } + + // Setup debounce callback + timeout = window.requestAnimationFrame((function () { + sortContents(contents); + publicAPIs.detect(); + })); + + }; + + /** + * Destroy the current instantiation + */ + publicAPIs.destroy = function () { + + // Undo DOM changes + if (current) { + deactivate(current, settings); + } + + // Remove event listeners + window.removeEventListener('scroll', scrollHandler, false); + if (settings.reflow) { + window.removeEventListener('resize', resizeHandler, false); + } + + // Reset variables + contents = null; + navItems = null; + current = null; + timeout = null; + settings = null; + + }; + + /** + * Initialize the current instantiation + */ + var init = function () { + + // Merge user options into defaults + settings = extend(defaults, options || {}); + + // Setup variables based on the current DOM + publicAPIs.setup(); + + // Find the currently active content + publicAPIs.detect(); + + // Setup event listeners + window.addEventListener('scroll', scrollHandler, false); + if (settings.reflow) { + window.addEventListener('resize', resizeHandler, false); + } + + }; + + + // + // Initialize and return the public APIs + // + + init(); + return publicAPIs; + + }; + + + // + // Return the Constructor + // + + return Constructor; + +})); \ No newline at end of file diff --git a/assets/js/plugins/jquery.ba-throttle-debounce.js b/assets/js/plugins/jquery.ba-throttle-debounce.js new file mode 100644 index 000000000..fa30bdfff --- /dev/null +++ b/assets/js/plugins/jquery.ba-throttle-debounce.js @@ -0,0 +1,252 @@ +/*! + * jQuery throttle / debounce - v1.1 - 3/7/2010 + * http://benalman.com/projects/jquery-throttle-debounce-plugin/ + * + * Copyright (c) 2010 "Cowboy" Ben Alman + * Dual licensed under the MIT and GPL licenses. + * http://benalman.com/about/license/ + */ + +// Script: jQuery throttle / debounce: Sometimes, less is more! +// +// *Version: 1.1, Last updated: 3/7/2010* +// +// Project Home - http://benalman.com/projects/jquery-throttle-debounce-plugin/ +// GitHub - http://github.com/cowboy/jquery-throttle-debounce/ +// Source - http://github.com/cowboy/jquery-throttle-debounce/raw/master/jquery.ba-throttle-debounce.js +// (Minified) - http://github.com/cowboy/jquery-throttle-debounce/raw/master/jquery.ba-throttle-debounce.min.js (0.7kb) +// +// About: License +// +// Copyright (c) 2010 "Cowboy" Ben Alman, +// Dual licensed under the MIT and GPL licenses. +// http://benalman.com/about/license/ +// +// About: Examples +// +// These working examples, complete with fully commented code, illustrate a few +// ways in which this plugin can be used. +// +// Throttle - http://benalman.com/code/projects/jquery-throttle-debounce/examples/throttle/ +// Debounce - http://benalman.com/code/projects/jquery-throttle-debounce/examples/debounce/ +// +// About: Support and Testing +// +// Information about what version or versions of jQuery this plugin has been +// tested with, what browsers it has been tested in, and where the unit tests +// reside (so you can test it yourself). +// +// jQuery Versions - none, 1.3.2, 1.4.2 +// Browsers Tested - Internet Explorer 6-8, Firefox 2-3.6, Safari 3-4, Chrome 4-5, Opera 9.6-10.1. +// Unit Tests - http://benalman.com/code/projects/jquery-throttle-debounce/unit/ +// +// About: Release History +// +// 1.1 - (3/7/2010) Fixed a bug in where trailing callbacks +// executed later than they should. Reworked a fair amount of internal +// logic as well. +// 1.0 - (3/6/2010) Initial release as a stand-alone project. Migrated over +// from jquery-misc repo v0.4 to jquery-throttle repo v1.0, added the +// no_trailing throttle parameter and debounce functionality. +// +// Topic: Note for non-jQuery users +// +// jQuery isn't actually required for this plugin, because nothing internal +// uses any jQuery methods or properties. jQuery is just used as a namespace +// under which these methods can exist. +// +// Since jQuery isn't actually required for this plugin, if jQuery doesn't exist +// when this plugin is loaded, the method described below will be created in +// the `Cowboy` namespace. Usage will be exactly the same, but instead of +// $.method() or jQuery.method(), you'll need to use Cowboy.method(). + +(function(window,undefined){ + '$:nomunge'; // Used by YUI compressor. + + // Since jQuery really isn't required for this plugin, use `jQuery` as the + // namespace only if it already exists, otherwise use the `Cowboy` namespace, + // creating it if necessary. + var $ = window.jQuery || window.Cowboy || ( window.Cowboy = {} ), + + // Internal method reference. + jq_throttle; + + // Method: jQuery.throttle + // + // Throttle execution of a function. Especially useful for rate limiting + // execution of handlers on events like resize and scroll. If you want to + // rate-limit execution of a function to a single time, see the + // method. + // + // In this visualization, | is a throttled-function call and X is the actual + // callback execution: + // + // > Throttled with `no_trailing` specified as false or unspecified: + // > ||||||||||||||||||||||||| (pause) ||||||||||||||||||||||||| + // > X X X X X X X X X X X X + // > + // > Throttled with `no_trailing` specified as true: + // > ||||||||||||||||||||||||| (pause) ||||||||||||||||||||||||| + // > X X X X X X X X X X + // + // Usage: + // + // > var throttled = jQuery.throttle( delay, [ no_trailing, ] callback ); + // > + // > jQuery('selector').bind( 'someevent', throttled ); + // > jQuery('selector').unbind( 'someevent', throttled ); + // + // This also works in jQuery 1.4+: + // + // > jQuery('selector').bind( 'someevent', jQuery.throttle( delay, [ no_trailing, ] callback ) ); + // > jQuery('selector').unbind( 'someevent', callback ); + // + // Arguments: + // + // delay - (Number) A zero-or-greater delay in milliseconds. For event + // callbacks, values around 100 or 250 (or even higher) are most useful. + // no_trailing - (Boolean) Optional, defaults to false. If no_trailing is + // true, callback will only execute every `delay` milliseconds while the + // throttled-function is being called. If no_trailing is false or + // unspecified, callback will be executed one final time after the last + // throttled-function call. (After the throttled-function has not been + // called for `delay` milliseconds, the internal counter is reset) + // callback - (Function) A function to be executed after delay milliseconds. + // The `this` context and all arguments are passed through, as-is, to + // `callback` when the throttled-function is executed. + // + // Returns: + // + // (Function) A new, throttled, function. + + $.throttle = jq_throttle = function( delay, no_trailing, callback, debounce_mode ) { + // After wrapper has stopped being called, this timeout ensures that + // `callback` is executed at the proper times in `throttle` and `end` + // debounce modes. + var timeout_id, + + // Keep track of the last time `callback` was executed. + last_exec = 0; + + // `no_trailing` defaults to falsy. + if ( typeof no_trailing !== 'boolean' ) { + debounce_mode = callback; + callback = no_trailing; + no_trailing = undefined; + } + + // The `wrapper` function encapsulates all of the throttling / debouncing + // functionality and when executed will limit the rate at which `callback` + // is executed. + function wrapper() { + var that = this, + elapsed = +new Date() - last_exec, + args = arguments; + + // Execute `callback` and update the `last_exec` timestamp. + function exec() { + last_exec = +new Date(); + callback.apply( that, args ); + }; + + // If `debounce_mode` is true (at_begin) this is used to clear the flag + // to allow future `callback` executions. + function clear() { + timeout_id = undefined; + }; + + if ( debounce_mode && !timeout_id ) { + // Since `wrapper` is being called for the first time and + // `debounce_mode` is true (at_begin), execute `callback`. + exec(); + } + + // Clear any existing timeout. + timeout_id && clearTimeout( timeout_id ); + + if ( debounce_mode === undefined && elapsed > delay ) { + // In throttle mode, if `delay` time has been exceeded, execute + // `callback`. + exec(); + + } else if ( no_trailing !== true ) { + // In trailing throttle mode, since `delay` time has not been + // exceeded, schedule `callback` to execute `delay` ms after most + // recent execution. + // + // If `debounce_mode` is true (at_begin), schedule `clear` to execute + // after `delay` ms. + // + // If `debounce_mode` is false (at end), schedule `callback` to + // execute after `delay` ms. + timeout_id = setTimeout( debounce_mode ? clear : exec, debounce_mode === undefined ? delay - elapsed : delay ); + } + }; + + // Set the guid of `wrapper` function to the same of original callback, so + // it can be removed in jQuery 1.4+ .unbind or .die by using the original + // callback as a reference. + if ( $.guid ) { + wrapper.guid = callback.guid = callback.guid || $.guid++; + } + + // Return the wrapper function. + return wrapper; + }; + + // Method: jQuery.debounce + // + // Debounce execution of a function. Debouncing, unlike throttling, + // guarantees that a function is only executed a single time, either at the + // very beginning of a series of calls, or at the very end. If you want to + // simply rate-limit execution of a function, see the + // method. + // + // In this visualization, | is a debounced-function call and X is the actual + // callback execution: + // + // > Debounced with `at_begin` specified as false or unspecified: + // > ||||||||||||||||||||||||| (pause) ||||||||||||||||||||||||| + // > X X + // > + // > Debounced with `at_begin` specified as true: + // > ||||||||||||||||||||||||| (pause) ||||||||||||||||||||||||| + // > X X + // + // Usage: + // + // > var debounced = jQuery.debounce( delay, [ at_begin, ] callback ); + // > + // > jQuery('selector').bind( 'someevent', debounced ); + // > jQuery('selector').unbind( 'someevent', debounced ); + // + // This also works in jQuery 1.4+: + // + // > jQuery('selector').bind( 'someevent', jQuery.debounce( delay, [ at_begin, ] callback ) ); + // > jQuery('selector').unbind( 'someevent', callback ); + // + // Arguments: + // + // delay - (Number) A zero-or-greater delay in milliseconds. For event + // callbacks, values around 100 or 250 (or even higher) are most useful. + // at_begin - (Boolean) Optional, defaults to false. If at_begin is false or + // unspecified, callback will only be executed `delay` milliseconds after + // the last debounced-function call. If at_begin is true, callback will be + // executed only at the first debounced-function call. (After the + // throttled-function has not been called for `delay` milliseconds, the + // internal counter is reset) + // callback - (Function) A function to be executed after delay milliseconds. + // The `this` context and all arguments are passed through, as-is, to + // `callback` when the debounced-function is executed. + // + // Returns: + // + // (Function) A new, debounced, function. + + $.debounce = function( delay, at_begin, callback ) { + return callback === undefined + ? jq_throttle( delay, at_begin, false ) + : jq_throttle( delay, callback, at_begin !== false ); + }; + +})(this); diff --git a/assets/js/plugins/jquery.fitvids.js b/assets/js/plugins/jquery.fitvids.js new file mode 100644 index 000000000..5c2f85c99 --- /dev/null +++ b/assets/js/plugins/jquery.fitvids.js @@ -0,0 +1,82 @@ +/*jshint browser:true */ +/*! +* FitVids 1.1 +* +* Copyright 2013, Chris Coyier - http://css-tricks.com + Dave Rupert - http://daverupert.com +* Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/ +* Released under the WTFPL license - http://sam.zoy.org/wtfpl/ +* +*/ + +;(function( $ ){ + + 'use strict'; + + $.fn.fitVids = function( options ) { + var settings = { + customSelector: null, + ignore: null + }; + + if(!document.getElementById('fit-vids-style')) { + // appendStyles: https://github.com/toddmotto/fluidvids/blob/master/dist/fluidvids.js + var head = document.head || document.getElementsByTagName('head')[0]; + var css = '.fluid-width-video-wrapper{width:100%;position:relative;padding:0;}.fluid-width-video-wrapper iframe,.fluid-width-video-wrapper object,.fluid-width-video-wrapper embed {position:absolute;top:0;left:0;width:100%;height:100%;}'; + var div = document.createElement("div"); + div.innerHTML = '

x

'; + head.appendChild(div.childNodes[1]); + } + + if ( options ) { + $.extend( settings, options ); + } + + return this.each(function(){ + var selectors = [ + 'iframe[src*="player.vimeo.com"]', + 'iframe[src*="youtube.com"]', + 'iframe[src*="youtube-nocookie.com"]', + 'iframe[src*="kickstarter.com"][src*="video.html"]', + 'object', + 'embed' + ]; + + if (settings.customSelector) { + selectors.push(settings.customSelector); + } + + var ignoreList = '.fitvidsignore'; + + if(settings.ignore) { + ignoreList = ignoreList + ', ' + settings.ignore; + } + + var $allVideos = $(this).find(selectors.join(',')); + $allVideos = $allVideos.not('object object'); // SwfObj conflict patch + $allVideos = $allVideos.not(ignoreList); // Disable FitVids on this video. + + $allVideos.each(function(count){ + var $this = $(this); + if($this.parents(ignoreList).length > 0) { + return; // Disable FitVids on this video. + } + if (this.tagName.toLowerCase() === 'embed' && $this.parent('object').length || $this.parent('.fluid-width-video-wrapper').length) { return; } + if ((!$this.css('height') && !$this.css('width')) && (isNaN($this.attr('height')) || isNaN($this.attr('width')))) + { + $this.attr('height', 9); + $this.attr('width', 16); + } + var height = ( this.tagName.toLowerCase() === 'object' || ($this.attr('height') && !isNaN(parseInt($this.attr('height'), 10))) ) ? parseInt($this.attr('height'), 10) : $this.height(), + width = !isNaN(parseInt($this.attr('width'), 10)) ? parseInt($this.attr('width'), 10) : $this.width(), + aspectRatio = height / width; + if(!$this.attr('id')){ + var videoID = 'fitvid' + count; + $this.attr('id', videoID); + } + $this.wrap('
').parent('.fluid-width-video-wrapper').css('padding-top', (aspectRatio * 100)+'%'); + $this.removeAttr('height').removeAttr('width'); + }); + }); + }; +// Works with either jQuery or Zepto +})( window.jQuery || window.Zepto ); \ No newline at end of file diff --git a/assets/js/plugins/jquery.greedy-navigation.js b/assets/js/plugins/jquery.greedy-navigation.js new file mode 100644 index 000000000..d8f323788 --- /dev/null +++ b/assets/js/plugins/jquery.greedy-navigation.js @@ -0,0 +1,127 @@ +/* +GreedyNav.js - http://lukejacksonn.com/actuate +Licensed under the MIT license - http://opensource.org/licenses/MIT +Copyright (c) 2015 Luke Jackson +*/ + +$(function() { + + var $btn = $("nav.greedy-nav .greedy-nav__toggle"); + var $vlinks = $("nav.greedy-nav .visible-links"); + var $hlinks = $("nav.greedy-nav .hidden-links"); + var $nav = $("nav.greedy-nav"); + var $logo = $('nav.greedy-nav .site-logo'); + var $logoImg = $('nav.greedy-nav .site-logo img'); + var $title = $("nav.greedy-nav .site-title"); + var $search = $('nav.greedy-nav button.search__toggle'); + + var numOfItems, totalSpace, closingTime, breakWidths; + + // This function measures both hidden and visible links and sets the navbar breakpoints + // This is called the first time the script runs and everytime the "check()" function detects a change of window width that reached a different CSS width breakpoint, which affects the size of navbar Items + // Please note that "CSS width breakpoints" (which are only 4) !== "navbar breakpoints" (which are as many as the number of items on the navbar) + function measureLinks(){ + numOfItems = 0; + totalSpace = 0; + closingTime = 1000; + breakWidths = []; + + // Adds the width of a navItem in order to create breakpoints for the navbar + function addWidth(i, w) { + totalSpace += w; + numOfItems += 1; + breakWidths.push(totalSpace); + } + + // Measures the width of hidden links by making a temporary clone of them and positioning under visible links + function hiddenWidth(obj){ + var clone = obj.clone(); + clone.css("visibility","hidden"); + $vlinks.append(clone); + addWidth(0, clone.outerWidth()); + clone.remove(); + } + // Measure both visible and hidden links widths + $vlinks.children().outerWidth(addWidth); + $hlinks.children().each(function(){hiddenWidth($(this))}); + } + // Get initial state + measureLinks(); + + var winWidth = $( window ).width(); + // Set the last measured CSS width breakpoint: 0: <768px, 1: <1024px, 2: < 1280px, 3: >= 1280px. + var lastBreakpoint = winWidth < 768 ? 0 : winWidth < 1024 ? 1 : winWidth < 1280 ? 2 : 3; + + var availableSpace, numOfVisibleItems, requiredSpace, timer; + + function check() { + + winWidth = $( window ).width(); + // Set the current CSS width breakpoint: 0: <768px, 1: <1024px, 2: < 1280px, 3: >= 1280px. + var curBreakpoint = winWidth < 768 ? 0 : winWidth < 1024 ? 1 : winWidth < 1280 ? 2 : 3; + // If current breakpoint is different from last measured breakpoint, measureLinks again + if(curBreakpoint !== lastBreakpoint) measureLinks(); + // Set the last measured CSS width breakpoint with the current breakpoint + lastBreakpoint = curBreakpoint; + + // Get instant state + numOfVisibleItems = $vlinks.children().length; + // Decrease the width of visible elements from the nav innerWidth to find out the available space for navItems + availableSpace = /* nav */ $nav.innerWidth() + - /* logo */ ($logo.length !== 0 ? $logo.outerWidth(true) : 0) + - /* title */ $title.outerWidth(true) + - /* search */ ($search.length !== 0 ? $search.outerWidth(true) : 0) + - /* toggle */ (numOfVisibleItems !== breakWidths.length ? $btn.outerWidth(true) : 0); + requiredSpace = breakWidths[numOfVisibleItems - 1]; + + // There is not enought space + if (requiredSpace > availableSpace) { + $vlinks.children().last().prependTo($hlinks); + numOfVisibleItems -= 1; + check(); + // There is more than enough space. If only one element is hidden, add the toggle width to the available space + } else if (availableSpace + (numOfVisibleItems === breakWidths.length - 1?$btn.outerWidth(true):0) > breakWidths[numOfVisibleItems]) { + $hlinks.children().first().appendTo($vlinks); + numOfVisibleItems += 1; + check(); + } + // Update the button accordingly + $btn.attr("count", numOfItems - numOfVisibleItems); + if (numOfVisibleItems === numOfItems) { + $btn.addClass('hidden'); + } else $btn.removeClass('hidden'); + } + + // Window listeners + $(window).resize(function() { + check(); + }); + + $btn.on('click', function() { + $hlinks.toggleClass('hidden'); + $(this).toggleClass('close'); + clearTimeout(timer); + }); + + $hlinks.on('mouseleave', function() { + // Mouse has left, start the timer + timer = setTimeout(function() { + $hlinks.addClass('hidden'); + }, closingTime); + }).on('mouseenter', function() { + // Mouse is back, cancel the timer + clearTimeout(timer); + }) + + // check if page has a logo + if($logoImg.length !== 0){ + // check if logo is not loaded + if(!($logoImg[0].complete || $logoImg[0].naturalWidth !== 0)){ + // if logo is not loaded wait for logo to load or fail to check + $logoImg.one("load error", check); + // if logo is already loaded just check + } else check(); + // if page does not have a logo just check + } else check(); + +}); diff --git a/assets/js/plugins/jquery.magnific-popup.js b/assets/js/plugins/jquery.magnific-popup.js new file mode 100644 index 000000000..7d1d19784 --- /dev/null +++ b/assets/js/plugins/jquery.magnific-popup.js @@ -0,0 +1,1860 @@ +/*! Magnific Popup - v1.1.0 - 2016-02-20 +* http://dimsemenov.com/plugins/magnific-popup/ +* Copyright (c) 2016 Dmitry Semenov; */ +;(function (factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else if (typeof exports === 'object') { + // Node/CommonJS + factory(require('jquery')); + } else { + // Browser globals + factory(window.jQuery || window.Zepto); + } + }(function($) { + + /*>>core*/ + /** + * + * Magnific Popup Core JS file + * + */ + + + /** + * Private static constants + */ + var CLOSE_EVENT = 'Close', + BEFORE_CLOSE_EVENT = 'BeforeClose', + AFTER_CLOSE_EVENT = 'AfterClose', + BEFORE_APPEND_EVENT = 'BeforeAppend', + MARKUP_PARSE_EVENT = 'MarkupParse', + OPEN_EVENT = 'Open', + CHANGE_EVENT = 'Change', + NS = 'mfp', + EVENT_NS = '.' + NS, + READY_CLASS = 'mfp-ready', + REMOVING_CLASS = 'mfp-removing', + PREVENT_CLOSE_CLASS = 'mfp-prevent-close'; + + + /** + * Private vars + */ + /*jshint -W079 */ + var mfp, // As we have only one instance of MagnificPopup object, we define it locally to not to use 'this' + MagnificPopup = function(){}, + _isJQ = !!(window.jQuery), + _prevStatus, + _window = $(window), + _document, + _prevContentType, + _wrapClasses, + _currPopupType; + + + /** + * Private functions + */ + var _mfpOn = function(name, f) { + mfp.ev.on(NS + name + EVENT_NS, f); + }, + _getEl = function(className, appendTo, html, raw) { + var el = document.createElement('div'); + el.className = 'mfp-'+className; + if(html) { + el.innerHTML = html; + } + if(!raw) { + el = $(el); + if(appendTo) { + el.appendTo(appendTo); + } + } else if(appendTo) { + appendTo.appendChild(el); + } + return el; + }, + _mfpTrigger = function(e, data) { + mfp.ev.triggerHandler(NS + e, data); + + if(mfp.st.callbacks) { + // converts "mfpEventName" to "eventName" callback and triggers it if it's present + e = e.charAt(0).toLowerCase() + e.slice(1); + if(mfp.st.callbacks[e]) { + mfp.st.callbacks[e].apply(mfp, $.isArray(data) ? data : [data]); + } + } + }, + _getCloseBtn = function(type) { + if(type !== _currPopupType || !mfp.currTemplate.closeBtn) { + mfp.currTemplate.closeBtn = $( mfp.st.closeMarkup.replace('%title%', mfp.st.tClose ) ); + _currPopupType = type; + } + return mfp.currTemplate.closeBtn; + }, + // Initialize Magnific Popup only when called at least once + _checkInstance = function() { + if(!$.magnificPopup.instance) { + /*jshint -W020 */ + mfp = new MagnificPopup(); + mfp.init(); + $.magnificPopup.instance = mfp; + } + }, + // CSS transition detection, http://stackoverflow.com/questions/7264899/detect-css-transitions-using-javascript-and-without-modernizr + supportsTransitions = function() { + var s = document.createElement('p').style, // 's' for style. better to create an element if body yet to exist + v = ['ms','O','Moz','Webkit']; // 'v' for vendor + + if( s['transition'] !== undefined ) { + return true; + } + + while( v.length ) { + if( v.pop() + 'Transition' in s ) { + return true; + } + } + + return false; + }; + + + + /** + * Public functions + */ + MagnificPopup.prototype = { + + constructor: MagnificPopup, + + /** + * Initializes Magnific Popup plugin. + * This function is triggered only once when $.fn.magnificPopup or $.magnificPopup is executed + */ + init: function() { + var appVersion = navigator.appVersion; + mfp.isLowIE = mfp.isIE8 = document.all && !document.addEventListener; + mfp.isAndroid = (/android/gi).test(appVersion); + mfp.isIOS = (/iphone|ipad|ipod/gi).test(appVersion); + mfp.supportsTransition = supportsTransitions(); + + // We disable fixed positioned lightbox on devices that don't handle it nicely. + // If you know a better way of detecting this - let me know. + mfp.probablyMobile = (mfp.isAndroid || mfp.isIOS || /(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent) ); + _document = $(document); + + mfp.popupsCache = {}; + }, + + /** + * Opens popup + * @param data [description] + */ + open: function(data) { + + var i; + + if(data.isObj === false) { + // convert jQuery collection to array to avoid conflicts later + mfp.items = data.items.toArray(); + + mfp.index = 0; + var items = data.items, + item; + for(i = 0; i < items.length; i++) { + item = items[i]; + if(item.parsed) { + item = item.el[0]; + } + if(item === data.el[0]) { + mfp.index = i; + break; + } + } + } else { + mfp.items = $.isArray(data.items) ? data.items : [data.items]; + mfp.index = data.index || 0; + } + + // if popup is already opened - we just update the content + if(mfp.isOpen) { + mfp.updateItemHTML(); + return; + } + + mfp.types = []; + _wrapClasses = ''; + if(data.mainEl && data.mainEl.length) { + mfp.ev = data.mainEl.eq(0); + } else { + mfp.ev = _document; + } + + if(data.key) { + if(!mfp.popupsCache[data.key]) { + mfp.popupsCache[data.key] = {}; + } + mfp.currTemplate = mfp.popupsCache[data.key]; + } else { + mfp.currTemplate = {}; + } + + + + mfp.st = $.extend(true, {}, $.magnificPopup.defaults, data ); + mfp.fixedContentPos = mfp.st.fixedContentPos === 'auto' ? !mfp.probablyMobile : mfp.st.fixedContentPos; + + if(mfp.st.modal) { + mfp.st.closeOnContentClick = false; + mfp.st.closeOnBgClick = false; + mfp.st.showCloseBtn = false; + mfp.st.enableEscapeKey = false; + } + + + // Building markup + // main containers are created only once + if(!mfp.bgOverlay) { + + // Dark overlay + mfp.bgOverlay = _getEl('bg').on('click'+EVENT_NS, function() { + mfp.close(); + }); + + mfp.wrap = _getEl('wrap').attr('tabindex', -1).on('click'+EVENT_NS, function(e) { + if(mfp._checkIfClose(e.target)) { + mfp.close(); + } + }); + + mfp.container = _getEl('container', mfp.wrap); + } + + mfp.contentContainer = _getEl('content'); + if(mfp.st.preloader) { + mfp.preloader = _getEl('preloader', mfp.container, mfp.st.tLoading); + } + + + // Initializing modules + var modules = $.magnificPopup.modules; + for(i = 0; i < modules.length; i++) { + var n = modules[i]; + n = n.charAt(0).toUpperCase() + n.slice(1); + mfp['init'+n].call(mfp); + } + _mfpTrigger('BeforeOpen'); + + + if(mfp.st.showCloseBtn) { + // Close button + if(!mfp.st.closeBtnInside) { + mfp.wrap.append( _getCloseBtn() ); + } else { + _mfpOn(MARKUP_PARSE_EVENT, function(e, template, values, item) { + values.close_replaceWith = _getCloseBtn(item.type); + }); + _wrapClasses += ' mfp-close-btn-in'; + } + } + + if(mfp.st.alignTop) { + _wrapClasses += ' mfp-align-top'; + } + + + + if(mfp.fixedContentPos) { + mfp.wrap.css({ + overflow: mfp.st.overflowY, + overflowX: 'hidden', + overflowY: mfp.st.overflowY + }); + } else { + mfp.wrap.css({ + top: _window.scrollTop(), + position: 'absolute' + }); + } + if( mfp.st.fixedBgPos === false || (mfp.st.fixedBgPos === 'auto' && !mfp.fixedContentPos) ) { + mfp.bgOverlay.css({ + height: _document.height(), + position: 'absolute' + }); + } + + + + if(mfp.st.enableEscapeKey) { + // Close on ESC key + _document.on('keyup' + EVENT_NS, function(e) { + if(e.keyCode === 27) { + mfp.close(); + } + }); + } + + _window.on('resize' + EVENT_NS, function() { + mfp.updateSize(); + }); + + + if(!mfp.st.closeOnContentClick) { + _wrapClasses += ' mfp-auto-cursor'; + } + + if(_wrapClasses) + mfp.wrap.addClass(_wrapClasses); + + + // this triggers recalculation of layout, so we get it once to not to trigger twice + var windowHeight = mfp.wH = _window.height(); + + + var windowStyles = {}; + + if( mfp.fixedContentPos ) { + if(mfp._hasScrollBar(windowHeight)){ + var s = mfp._getScrollbarSize(); + if(s) { + windowStyles.marginRight = s; + } + } + } + + if(mfp.fixedContentPos) { + if(!mfp.isIE7) { + windowStyles.overflow = 'hidden'; + } else { + // ie7 double-scroll bug + $('body, html').css('overflow', 'hidden'); + } + } + + + + var classesToadd = mfp.st.mainClass; + if(mfp.isIE7) { + classesToadd += ' mfp-ie7'; + } + if(classesToadd) { + mfp._addClassToMFP( classesToadd ); + } + + // add content + mfp.updateItemHTML(); + + _mfpTrigger('BuildControls'); + + // remove scrollbar, add margin e.t.c + $('html').css(windowStyles); + + // add everything to DOM + mfp.bgOverlay.add(mfp.wrap).prependTo( mfp.st.prependTo || $(document.body) ); + + // Save last focused element + mfp._lastFocusedEl = document.activeElement; + + // Wait for next cycle to allow CSS transition + setTimeout(function() { + + if(mfp.content) { + mfp._addClassToMFP(READY_CLASS); + mfp._setFocus(); + } else { + // if content is not defined (not loaded e.t.c) we add class only for BG + mfp.bgOverlay.addClass(READY_CLASS); + } + + // Trap the focus in popup + _document.on('focusin' + EVENT_NS, mfp._onFocusIn); + + }, 16); + + mfp.isOpen = true; + mfp.updateSize(windowHeight); + _mfpTrigger(OPEN_EVENT); + + return data; + }, + + /** + * Closes the popup + */ + close: function() { + if(!mfp.isOpen) return; + _mfpTrigger(BEFORE_CLOSE_EVENT); + + mfp.isOpen = false; + // for CSS3 animation + if(mfp.st.removalDelay && !mfp.isLowIE && mfp.supportsTransition ) { + mfp._addClassToMFP(REMOVING_CLASS); + setTimeout(function() { + mfp._close(); + }, mfp.st.removalDelay); + } else { + mfp._close(); + } + }, + + /** + * Helper for close() function + */ + _close: function() { + _mfpTrigger(CLOSE_EVENT); + + var classesToRemove = REMOVING_CLASS + ' ' + READY_CLASS + ' '; + + mfp.bgOverlay.detach(); + mfp.wrap.detach(); + mfp.container.empty(); + + if(mfp.st.mainClass) { + classesToRemove += mfp.st.mainClass + ' '; + } + + mfp._removeClassFromMFP(classesToRemove); + + if(mfp.fixedContentPos) { + var windowStyles = {marginRight: ''}; + if(mfp.isIE7) { + $('body, html').css('overflow', ''); + } else { + windowStyles.overflow = ''; + } + $('html').css(windowStyles); + } + + _document.off('keyup' + EVENT_NS + ' focusin' + EVENT_NS); + mfp.ev.off(EVENT_NS); + + // clean up DOM elements that aren't removed + mfp.wrap.attr('class', 'mfp-wrap').removeAttr('style'); + mfp.bgOverlay.attr('class', 'mfp-bg'); + mfp.container.attr('class', 'mfp-container'); + + // remove close button from target element + if(mfp.st.showCloseBtn && + (!mfp.st.closeBtnInside || mfp.currTemplate[mfp.currItem.type] === true)) { + if(mfp.currTemplate.closeBtn) + mfp.currTemplate.closeBtn.detach(); + } + + + if(mfp.st.autoFocusLast && mfp._lastFocusedEl) { + $(mfp._lastFocusedEl).focus(); // put tab focus back + } + mfp.currItem = null; + mfp.content = null; + mfp.currTemplate = null; + mfp.prevHeight = 0; + + _mfpTrigger(AFTER_CLOSE_EVENT); + }, + + updateSize: function(winHeight) { + + if(mfp.isIOS) { + // fixes iOS nav bars https://github.com/dimsemenov/Magnific-Popup/issues/2 + var zoomLevel = document.documentElement.clientWidth / window.innerWidth; + var height = window.innerHeight * zoomLevel; + mfp.wrap.css('height', height); + mfp.wH = height; + } else { + mfp.wH = winHeight || _window.height(); + } + // Fixes #84: popup incorrectly positioned with position:relative on body + if(!mfp.fixedContentPos) { + mfp.wrap.css('height', mfp.wH); + } + + _mfpTrigger('Resize'); + + }, + + /** + * Set content of popup based on current index + */ + updateItemHTML: function() { + var item = mfp.items[mfp.index]; + + // Detach and perform modifications + mfp.contentContainer.detach(); + + if(mfp.content) + mfp.content.detach(); + + if(!item.parsed) { + item = mfp.parseEl( mfp.index ); + } + + var type = item.type; + + _mfpTrigger('BeforeChange', [mfp.currItem ? mfp.currItem.type : '', type]); + // BeforeChange event works like so: + // _mfpOn('BeforeChange', function(e, prevType, newType) { }); + + mfp.currItem = item; + + if(!mfp.currTemplate[type]) { + var markup = mfp.st[type] ? mfp.st[type].markup : false; + + // allows to modify markup + _mfpTrigger('FirstMarkupParse', markup); + + if(markup) { + mfp.currTemplate[type] = $(markup); + } else { + // if there is no markup found we just define that template is parsed + mfp.currTemplate[type] = true; + } + } + + if(_prevContentType && _prevContentType !== item.type) { + mfp.container.removeClass('mfp-'+_prevContentType+'-holder'); + } + + var newContent = mfp['get' + type.charAt(0).toUpperCase() + type.slice(1)](item, mfp.currTemplate[type]); + mfp.appendContent(newContent, type); + + item.preloaded = true; + + _mfpTrigger(CHANGE_EVENT, item); + _prevContentType = item.type; + + // Append container back after its content changed + mfp.container.prepend(mfp.contentContainer); + + _mfpTrigger('AfterChange'); + }, + + + /** + * Set HTML content of popup + */ + appendContent: function(newContent, type) { + mfp.content = newContent; + + if(newContent) { + if(mfp.st.showCloseBtn && mfp.st.closeBtnInside && + mfp.currTemplate[type] === true) { + // if there is no markup, we just append close button element inside + if(!mfp.content.find('.mfp-close').length) { + mfp.content.append(_getCloseBtn()); + } + } else { + mfp.content = newContent; + } + } else { + mfp.content = ''; + } + + _mfpTrigger(BEFORE_APPEND_EVENT); + mfp.container.addClass('mfp-'+type+'-holder'); + + mfp.contentContainer.append(mfp.content); + }, + + + /** + * Creates Magnific Popup data object based on given data + * @param {int} index Index of item to parse + */ + parseEl: function(index) { + var item = mfp.items[index], + type; + + if(item.tagName) { + item = { el: $(item) }; + } else { + type = item.type; + item = { data: item, src: item.src }; + } + + if(item.el) { + var types = mfp.types; + + // check for 'mfp-TYPE' class + for(var i = 0; i < types.length; i++) { + if( item.el.hasClass('mfp-'+types[i]) ) { + type = types[i]; + break; + } + } + + item.src = item.el.attr('data-mfp-src'); + if(!item.src) { + item.src = item.el.attr('href'); + } + } + + item.type = type || mfp.st.type || 'inline'; + item.index = index; + item.parsed = true; + mfp.items[index] = item; + _mfpTrigger('ElementParse', item); + + return mfp.items[index]; + }, + + + /** + * Initializes single popup or a group of popups + */ + addGroup: function(el, options) { + var eHandler = function(e) { + e.mfpEl = this; + mfp._openClick(e, el, options); + }; + + if(!options) { + options = {}; + } + + var eName = 'click.magnificPopup'; + options.mainEl = el; + + if(options.items) { + options.isObj = true; + el.off(eName).on(eName, eHandler); + } else { + options.isObj = false; + if(options.delegate) { + el.off(eName).on(eName, options.delegate , eHandler); + } else { + options.items = el; + el.off(eName).on(eName, eHandler); + } + } + }, + _openClick: function(e, el, options) { + var midClick = options.midClick !== undefined ? options.midClick : $.magnificPopup.defaults.midClick; + + + if(!midClick && ( e.which === 2 || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey ) ) { + return; + } + + var disableOn = options.disableOn !== undefined ? options.disableOn : $.magnificPopup.defaults.disableOn; + + if(disableOn) { + if($.isFunction(disableOn)) { + if( !disableOn.call(mfp) ) { + return true; + } + } else { // else it's number + if( _window.width() < disableOn ) { + return true; + } + } + } + + if(e.type) { + e.preventDefault(); + + // This will prevent popup from closing if element is inside and popup is already opened + if(mfp.isOpen) { + e.stopPropagation(); + } + } + + options.el = $(e.mfpEl); + if(options.delegate) { + options.items = el.find(options.delegate); + } + mfp.open(options); + }, + + + /** + * Updates text on preloader + */ + updateStatus: function(status, text) { + + if(mfp.preloader) { + if(_prevStatus !== status) { + mfp.container.removeClass('mfp-s-'+_prevStatus); + } + + if(!text && status === 'loading') { + text = mfp.st.tLoading; + } + + var data = { + status: status, + text: text + }; + // allows to modify status + _mfpTrigger('UpdateStatus', data); + + status = data.status; + text = data.text; + + mfp.preloader.html(text); + + mfp.preloader.find('a').on('click', function(e) { + e.stopImmediatePropagation(); + }); + + mfp.container.addClass('mfp-s-'+status); + _prevStatus = status; + } + }, + + + /* + "Private" helpers that aren't private at all + */ + // Check to close popup or not + // "target" is an element that was clicked + _checkIfClose: function(target) { + + if($(target).hasClass(PREVENT_CLOSE_CLASS)) { + return; + } + + var closeOnContent = mfp.st.closeOnContentClick; + var closeOnBg = mfp.st.closeOnBgClick; + + if(closeOnContent && closeOnBg) { + return true; + } else { + + // We close the popup if click is on close button or on preloader. Or if there is no content. + if(!mfp.content || $(target).hasClass('mfp-close') || (mfp.preloader && target === mfp.preloader[0]) ) { + return true; + } + + // if click is outside the content + if( (target !== mfp.content[0] && !$.contains(mfp.content[0], target)) ) { + if(closeOnBg) { + // last check, if the clicked element is in DOM, (in case it's removed onclick) + if( $.contains(document, target) ) { + return true; + } + } + } else if(closeOnContent) { + return true; + } + + } + return false; + }, + _addClassToMFP: function(cName) { + mfp.bgOverlay.addClass(cName); + mfp.wrap.addClass(cName); + }, + _removeClassFromMFP: function(cName) { + this.bgOverlay.removeClass(cName); + mfp.wrap.removeClass(cName); + }, + _hasScrollBar: function(winHeight) { + return ( (mfp.isIE7 ? _document.height() : document.body.scrollHeight) > (winHeight || _window.height()) ); + }, + _setFocus: function() { + (mfp.st.focus ? mfp.content.find(mfp.st.focus).eq(0) : mfp.wrap).focus(); + }, + _onFocusIn: function(e) { + if( e.target !== mfp.wrap[0] && !$.contains(mfp.wrap[0], e.target) ) { + mfp._setFocus(); + return false; + } + }, + _parseMarkup: function(template, values, item) { + var arr; + if(item.data) { + values = $.extend(item.data, values); + } + _mfpTrigger(MARKUP_PARSE_EVENT, [template, values, item] ); + + $.each(values, function(key, value) { + if(value === undefined || value === false) { + return true; + } + arr = key.split('_'); + if(arr.length > 1) { + var el = template.find(EVENT_NS + '-'+arr[0]); + + if(el.length > 0) { + var attr = arr[1]; + if(attr === 'replaceWith') { + if(el[0] !== value[0]) { + el.replaceWith(value); + } + } else if(attr === 'img') { + if(el.is('img')) { + el.attr('src', value); + } else { + el.replaceWith( $('').attr('src', value).attr('class', el.attr('class')) ); + } + } else { + el.attr(arr[1], value); + } + } + + } else { + template.find(EVENT_NS + '-'+key).html(value); + } + }); + }, + + _getScrollbarSize: function() { + // thx David + if(mfp.scrollbarSize === undefined) { + var scrollDiv = document.createElement("div"); + scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;'; + document.body.appendChild(scrollDiv); + mfp.scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth; + document.body.removeChild(scrollDiv); + } + return mfp.scrollbarSize; + } + + }; /* MagnificPopup core prototype end */ + + + + + /** + * Public static functions + */ + $.magnificPopup = { + instance: null, + proto: MagnificPopup.prototype, + modules: [], + + open: function(options, index) { + _checkInstance(); + + if(!options) { + options = {}; + } else { + options = $.extend(true, {}, options); + } + + options.isObj = true; + options.index = index || 0; + return this.instance.open(options); + }, + + close: function() { + return $.magnificPopup.instance && $.magnificPopup.instance.close(); + }, + + registerModule: function(name, module) { + if(module.options) { + $.magnificPopup.defaults[name] = module.options; + } + $.extend(this.proto, module.proto); + this.modules.push(name); + }, + + defaults: { + + // Info about options is in docs: + // http://dimsemenov.com/plugins/magnific-popup/documentation.html#options + + disableOn: 0, + + key: null, + + midClick: false, + + mainClass: '', + + preloader: true, + + focus: '', // CSS selector of input to focus after popup is opened + + closeOnContentClick: false, + + closeOnBgClick: true, + + closeBtnInside: true, + + showCloseBtn: true, + + enableEscapeKey: true, + + modal: false, + + alignTop: false, + + removalDelay: 0, + + prependTo: null, + + fixedContentPos: 'auto', + + fixedBgPos: 'auto', + + overflowY: 'auto', + + closeMarkup: '', + + tClose: 'Close (Esc)', + + tLoading: 'Loading...', + + autoFocusLast: true + + } + }; + + + + $.fn.magnificPopup = function(options) { + _checkInstance(); + + var jqEl = $(this); + + // We call some API method of first param is a string + if (typeof options === "string" ) { + + if(options === 'open') { + var items, + itemOpts = _isJQ ? jqEl.data('magnificPopup') : jqEl[0].magnificPopup, + index = parseInt(arguments[1], 10) || 0; + + if(itemOpts.items) { + items = itemOpts.items[index]; + } else { + items = jqEl; + if(itemOpts.delegate) { + items = items.find(itemOpts.delegate); + } + items = items.eq( index ); + } + mfp._openClick({mfpEl:items}, jqEl, itemOpts); + } else { + if(mfp.isOpen) + mfp[options].apply(mfp, Array.prototype.slice.call(arguments, 1)); + } + + } else { + // clone options obj + options = $.extend(true, {}, options); + + /* + * As Zepto doesn't support .data() method for objects + * and it works only in normal browsers + * we assign "options" object directly to the DOM element. FTW! + */ + if(_isJQ) { + jqEl.data('magnificPopup', options); + } else { + jqEl[0].magnificPopup = options; + } + + mfp.addGroup(jqEl, options); + + } + return jqEl; + }; + + /*>>core*/ + + /*>>inline*/ + + var INLINE_NS = 'inline', + _hiddenClass, + _inlinePlaceholder, + _lastInlineElement, + _putInlineElementsBack = function() { + if(_lastInlineElement) { + _inlinePlaceholder.after( _lastInlineElement.addClass(_hiddenClass) ).detach(); + _lastInlineElement = null; + } + }; + + $.magnificPopup.registerModule(INLINE_NS, { + options: { + hiddenClass: 'hide', // will be appended with `mfp-` prefix + markup: '', + tNotFound: 'Content not found' + }, + proto: { + + initInline: function() { + mfp.types.push(INLINE_NS); + + _mfpOn(CLOSE_EVENT+'.'+INLINE_NS, function() { + _putInlineElementsBack(); + }); + }, + + getInline: function(item, template) { + + _putInlineElementsBack(); + + if(item.src) { + var inlineSt = mfp.st.inline, + el = $(item.src); + + if(el.length) { + + // If target element has parent - we replace it with placeholder and put it back after popup is closed + var parent = el[0].parentNode; + if(parent && parent.tagName) { + if(!_inlinePlaceholder) { + _hiddenClass = inlineSt.hiddenClass; + _inlinePlaceholder = _getEl(_hiddenClass); + _hiddenClass = 'mfp-'+_hiddenClass; + } + // replace target inline element with placeholder + _lastInlineElement = el.after(_inlinePlaceholder).detach().removeClass(_hiddenClass); + } + + mfp.updateStatus('ready'); + } else { + mfp.updateStatus('error', inlineSt.tNotFound); + el = $('
'); + } + + item.inlineElement = el; + return el; + } + + mfp.updateStatus('ready'); + mfp._parseMarkup(template, {}, item); + return template; + } + } + }); + + /*>>inline*/ + + /*>>ajax*/ + var AJAX_NS = 'ajax', + _ajaxCur, + _removeAjaxCursor = function() { + if(_ajaxCur) { + $(document.body).removeClass(_ajaxCur); + } + }, + _destroyAjaxRequest = function() { + _removeAjaxCursor(); + if(mfp.req) { + mfp.req.abort(); + } + }; + + $.magnificPopup.registerModule(AJAX_NS, { + + options: { + settings: null, + cursor: 'mfp-ajax-cur', + tError: 'The content could not be loaded.' + }, + + proto: { + initAjax: function() { + mfp.types.push(AJAX_NS); + _ajaxCur = mfp.st.ajax.cursor; + + _mfpOn(CLOSE_EVENT+'.'+AJAX_NS, _destroyAjaxRequest); + _mfpOn('BeforeChange.' + AJAX_NS, _destroyAjaxRequest); + }, + getAjax: function(item) { + + if(_ajaxCur) { + $(document.body).addClass(_ajaxCur); + } + + mfp.updateStatus('loading'); + + var opts = $.extend({ + url: item.src, + success: function(data, textStatus, jqXHR) { + var temp = { + data:data, + xhr:jqXHR + }; + + _mfpTrigger('ParseAjax', temp); + + mfp.appendContent( $(temp.data), AJAX_NS ); + + item.finished = true; + + _removeAjaxCursor(); + + mfp._setFocus(); + + setTimeout(function() { + mfp.wrap.addClass(READY_CLASS); + }, 16); + + mfp.updateStatus('ready'); + + _mfpTrigger('AjaxContentAdded'); + }, + error: function() { + _removeAjaxCursor(); + item.finished = item.loadError = true; + mfp.updateStatus('error', mfp.st.ajax.tError.replace('%url%', item.src)); + } + }, mfp.st.ajax.settings); + + mfp.req = $.ajax(opts); + + return ''; + } + } + }); + + /*>>ajax*/ + + /*>>image*/ + var _imgInterval, + _getTitle = function(item) { + if(item.data && item.data.title !== undefined) + return item.data.title; + + var src = mfp.st.image.titleSrc; + + if(src) { + if($.isFunction(src)) { + return src.call(mfp, item); + } else if(item.el) { + return item.el.attr(src) || ''; + } + } + return ''; + }; + + $.magnificPopup.registerModule('image', { + + options: { + markup: '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + '
', + cursor: 'mfp-zoom-out-cur', + titleSrc: 'title', + verticalFit: true, + tError: 'The image could not be loaded.' + }, + + proto: { + initImage: function() { + var imgSt = mfp.st.image, + ns = '.image'; + + mfp.types.push('image'); + + _mfpOn(OPEN_EVENT+ns, function() { + if(mfp.currItem.type === 'image' && imgSt.cursor) { + $(document.body).addClass(imgSt.cursor); + } + }); + + _mfpOn(CLOSE_EVENT+ns, function() { + if(imgSt.cursor) { + $(document.body).removeClass(imgSt.cursor); + } + _window.off('resize' + EVENT_NS); + }); + + _mfpOn('Resize'+ns, mfp.resizeImage); + if(mfp.isLowIE) { + _mfpOn('AfterChange', mfp.resizeImage); + } + }, + resizeImage: function() { + var item = mfp.currItem; + if(!item || !item.img) return; + + if(mfp.st.image.verticalFit) { + var decr = 0; + // fix box-sizing in ie7/8 + if(mfp.isLowIE) { + decr = parseInt(item.img.css('padding-top'), 10) + parseInt(item.img.css('padding-bottom'),10); + } + item.img.css('max-height', mfp.wH-decr); + } + }, + _onImageHasSize: function(item) { + if(item.img) { + + item.hasSize = true; + + if(_imgInterval) { + clearInterval(_imgInterval); + } + + item.isCheckingImgSize = false; + + _mfpTrigger('ImageHasSize', item); + + if(item.imgHidden) { + if(mfp.content) + mfp.content.removeClass('mfp-loading'); + + item.imgHidden = false; + } + + } + }, + + /** + * Function that loops until the image has size to display elements that rely on it asap + */ + findImageSize: function(item) { + + var counter = 0, + img = item.img[0], + mfpSetInterval = function(delay) { + + if(_imgInterval) { + clearInterval(_imgInterval); + } + // decelerating interval that checks for size of an image + _imgInterval = setInterval(function() { + if(img.naturalWidth > 0) { + mfp._onImageHasSize(item); + return; + } + + if(counter > 200) { + clearInterval(_imgInterval); + } + + counter++; + if(counter === 3) { + mfpSetInterval(10); + } else if(counter === 40) { + mfpSetInterval(50); + } else if(counter === 100) { + mfpSetInterval(500); + } + }, delay); + }; + + mfpSetInterval(1); + }, + + getImage: function(item, template) { + + var guard = 0, + + // image load complete handler + onLoadComplete = function() { + if(item) { + if (item.img[0].complete) { + item.img.off('.mfploader'); + + if(item === mfp.currItem){ + mfp._onImageHasSize(item); + + mfp.updateStatus('ready'); + } + + item.hasSize = true; + item.loaded = true; + + _mfpTrigger('ImageLoadComplete'); + + } + else { + // if image complete check fails 200 times (20 sec), we assume that there was an error. + guard++; + if(guard < 200) { + setTimeout(onLoadComplete,100); + } else { + onLoadError(); + } + } + } + }, + + // image error handler + onLoadError = function() { + if(item) { + item.img.off('.mfploader'); + if(item === mfp.currItem){ + mfp._onImageHasSize(item); + mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) ); + } + + item.hasSize = true; + item.loaded = true; + item.loadError = true; + } + }, + imgSt = mfp.st.image; + + + var el = template.find('.mfp-img'); + if(el.length) { + var img = document.createElement('img'); + img.className = 'mfp-img'; + if(item.el && item.el.find('img').length) { + img.alt = item.el.find('img').attr('alt'); + } + item.img = $(img).on('load.mfploader', onLoadComplete).on('error.mfploader', onLoadError); + img.src = item.src; + + // without clone() "error" event is not firing when IMG is replaced by new IMG + // TODO: find a way to avoid such cloning + if(el.is('img')) { + item.img = item.img.clone(); + } + + img = item.img[0]; + if(img.naturalWidth > 0) { + item.hasSize = true; + } else if(!img.width) { + item.hasSize = false; + } + } + + mfp._parseMarkup(template, { + title: _getTitle(item), + img_replaceWith: item.img + }, item); + + mfp.resizeImage(); + + if(item.hasSize) { + if(_imgInterval) clearInterval(_imgInterval); + + if(item.loadError) { + template.addClass('mfp-loading'); + mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) ); + } else { + template.removeClass('mfp-loading'); + mfp.updateStatus('ready'); + } + return template; + } + + mfp.updateStatus('loading'); + item.loading = true; + + if(!item.hasSize) { + item.imgHidden = true; + template.addClass('mfp-loading'); + mfp.findImageSize(item); + } + + return template; + } + } + }); + + /*>>image*/ + + /*>>zoom*/ + var hasMozTransform, + getHasMozTransform = function() { + if(hasMozTransform === undefined) { + hasMozTransform = document.createElement('p').style.MozTransform !== undefined; + } + return hasMozTransform; + }; + + $.magnificPopup.registerModule('zoom', { + + options: { + enabled: false, + easing: 'ease-in-out', + duration: 300, + opener: function(element) { + return element.is('img') ? element : element.find('img'); + } + }, + + proto: { + + initZoom: function() { + var zoomSt = mfp.st.zoom, + ns = '.zoom', + image; + + if(!zoomSt.enabled || !mfp.supportsTransition) { + return; + } + + var duration = zoomSt.duration, + getElToAnimate = function(image) { + var newImg = image.clone().removeAttr('style').removeAttr('class').addClass('mfp-animated-image'), + transition = 'all '+(zoomSt.duration/1000)+'s ' + zoomSt.easing, + cssObj = { + position: 'fixed', + zIndex: 9999, + left: 0, + top: 0, + '-webkit-backface-visibility': 'hidden' + }, + t = 'transition'; + + cssObj['-webkit-'+t] = cssObj['-moz-'+t] = cssObj['-o-'+t] = cssObj[t] = transition; + + newImg.css(cssObj); + return newImg; + }, + showMainContent = function() { + mfp.content.css('visibility', 'visible'); + }, + openTimeout, + animatedImg; + + _mfpOn('BuildControls'+ns, function() { + if(mfp._allowZoom()) { + + clearTimeout(openTimeout); + mfp.content.css('visibility', 'hidden'); + + // Basically, all code below does is clones existing image, puts in on top of the current one and animated it + + image = mfp._getItemToZoom(); + + if(!image) { + showMainContent(); + return; + } + + animatedImg = getElToAnimate(image); + + animatedImg.css( mfp._getOffset() ); + + mfp.wrap.append(animatedImg); + + openTimeout = setTimeout(function() { + animatedImg.css( mfp._getOffset( true ) ); + openTimeout = setTimeout(function() { + + showMainContent(); + + setTimeout(function() { + animatedImg.remove(); + image = animatedImg = null; + _mfpTrigger('ZoomAnimationEnded'); + }, 16); // avoid blink when switching images + + }, duration); // this timeout equals animation duration + + }, 16); // by adding this timeout we avoid short glitch at the beginning of animation + + + // Lots of timeouts... + } + }); + _mfpOn(BEFORE_CLOSE_EVENT+ns, function() { + if(mfp._allowZoom()) { + + clearTimeout(openTimeout); + + mfp.st.removalDelay = duration; + + if(!image) { + image = mfp._getItemToZoom(); + if(!image) { + return; + } + animatedImg = getElToAnimate(image); + } + + animatedImg.css( mfp._getOffset(true) ); + mfp.wrap.append(animatedImg); + mfp.content.css('visibility', 'hidden'); + + setTimeout(function() { + animatedImg.css( mfp._getOffset() ); + }, 16); + } + + }); + + _mfpOn(CLOSE_EVENT+ns, function() { + if(mfp._allowZoom()) { + showMainContent(); + if(animatedImg) { + animatedImg.remove(); + } + image = null; + } + }); + }, + + _allowZoom: function() { + return mfp.currItem.type === 'image'; + }, + + _getItemToZoom: function() { + if(mfp.currItem.hasSize) { + return mfp.currItem.img; + } else { + return false; + } + }, + + // Get element postion relative to viewport + _getOffset: function(isLarge) { + var el; + if(isLarge) { + el = mfp.currItem.img; + } else { + el = mfp.st.zoom.opener(mfp.currItem.el || mfp.currItem); + } + + var offset = el.offset(); + var paddingTop = parseInt(el.css('padding-top'),10); + var paddingBottom = parseInt(el.css('padding-bottom'),10); + offset.top -= ( $(window).scrollTop() - paddingTop ); + + + /* + + Animating left + top + width/height looks glitchy in Firefox, but perfect in Chrome. And vice-versa. + + */ + var obj = { + width: el.width(), + // fix Zepto height+padding issue + height: (_isJQ ? el.innerHeight() : el[0].offsetHeight) - paddingBottom - paddingTop + }; + + // I hate to do this, but there is no another option + if( getHasMozTransform() ) { + obj['-moz-transform'] = obj['transform'] = 'translate(' + offset.left + 'px,' + offset.top + 'px)'; + } else { + obj.left = offset.left; + obj.top = offset.top; + } + return obj; + } + + } + }); + + + + /*>>zoom*/ + + /*>>iframe*/ + + var IFRAME_NS = 'iframe', + _emptyPage = '//about:blank', + + _fixIframeBugs = function(isShowing) { + if(mfp.currTemplate[IFRAME_NS]) { + var el = mfp.currTemplate[IFRAME_NS].find('iframe'); + if(el.length) { + // reset src after the popup is closed to avoid "video keeps playing after popup is closed" bug + if(!isShowing) { + el[0].src = _emptyPage; + } + + // IE8 black screen bug fix + if(mfp.isIE8) { + el.css('display', isShowing ? 'block' : 'none'); + } + } + } + }; + + $.magnificPopup.registerModule(IFRAME_NS, { + + options: { + markup: '
'+ + '
'+ + ''+ + '
', + + srcAction: 'iframe_src', + + // we don't care and support only one default type of URL by default + patterns: { + youtube: { + index: 'youtube.com', + id: 'v=', + src: '//www.youtube.com/embed/%id%?autoplay=1' + }, + vimeo: { + index: 'vimeo.com/', + id: '/', + src: '//player.vimeo.com/video/%id%?autoplay=1' + }, + gmaps: { + index: '//maps.google.', + src: '%id%&output=embed' + } + } + }, + + proto: { + initIframe: function() { + mfp.types.push(IFRAME_NS); + + _mfpOn('BeforeChange', function(e, prevType, newType) { + if(prevType !== newType) { + if(prevType === IFRAME_NS) { + _fixIframeBugs(); // iframe if removed + } else if(newType === IFRAME_NS) { + _fixIframeBugs(true); // iframe is showing + } + }// else { + // iframe source is switched, don't do anything + //} + }); + + _mfpOn(CLOSE_EVENT + '.' + IFRAME_NS, function() { + _fixIframeBugs(); + }); + }, + + getIframe: function(item, template) { + var embedSrc = item.src; + var iframeSt = mfp.st.iframe; + + $.each(iframeSt.patterns, function() { + if(embedSrc.indexOf( this.index ) > -1) { + if(this.id) { + if(typeof this.id === 'string') { + embedSrc = embedSrc.substr(embedSrc.lastIndexOf(this.id)+this.id.length, embedSrc.length); + } else { + embedSrc = this.id.call( this, embedSrc ); + } + } + embedSrc = this.src.replace('%id%', embedSrc ); + return false; // break; + } + }); + + var dataObj = {}; + if(iframeSt.srcAction) { + dataObj[iframeSt.srcAction] = embedSrc; + } + mfp._parseMarkup(template, dataObj, item); + + mfp.updateStatus('ready'); + + return template; + } + } + }); + + + + /*>>iframe*/ + + /*>>gallery*/ + /** + * Get looped index depending on number of slides + */ + var _getLoopedId = function(index) { + var numSlides = mfp.items.length; + if(index > numSlides - 1) { + return index - numSlides; + } else if(index < 0) { + return numSlides + index; + } + return index; + }, + _replaceCurrTotal = function(text, curr, total) { + return text.replace(/%curr%/gi, curr + 1).replace(/%total%/gi, total); + }; + + $.magnificPopup.registerModule('gallery', { + + options: { + enabled: false, + arrowMarkup: '', + preload: [0,2], + navigateByImgClick: true, + arrows: true, + + tPrev: 'Previous (Left arrow key)', + tNext: 'Next (Right arrow key)', + tCounter: '%curr% of %total%' + }, + + proto: { + initGallery: function() { + + var gSt = mfp.st.gallery, + ns = '.mfp-gallery'; + + mfp.direction = true; // true - next, false - prev + + if(!gSt || !gSt.enabled ) return false; + + _wrapClasses += ' mfp-gallery'; + + _mfpOn(OPEN_EVENT+ns, function() { + + if(gSt.navigateByImgClick) { + mfp.wrap.on('click'+ns, '.mfp-img', function() { + if(mfp.items.length > 1) { + mfp.next(); + return false; + } + }); + } + + _document.on('keydown'+ns, function(e) { + if (e.keyCode === 37) { + mfp.prev(); + } else if (e.keyCode === 39) { + mfp.next(); + } + }); + }); + + _mfpOn('UpdateStatus'+ns, function(e, data) { + if(data.text) { + data.text = _replaceCurrTotal(data.text, mfp.currItem.index, mfp.items.length); + } + }); + + _mfpOn(MARKUP_PARSE_EVENT+ns, function(e, element, values, item) { + var l = mfp.items.length; + values.counter = l > 1 ? _replaceCurrTotal(gSt.tCounter, item.index, l) : ''; + }); + + _mfpOn('BuildControls' + ns, function() { + if(mfp.items.length > 1 && gSt.arrows && !mfp.arrowLeft) { + var markup = gSt.arrowMarkup, + arrowLeft = mfp.arrowLeft = $( markup.replace(/%title%/gi, gSt.tPrev).replace(/%dir%/gi, 'left') ).addClass(PREVENT_CLOSE_CLASS), + arrowRight = mfp.arrowRight = $( markup.replace(/%title%/gi, gSt.tNext).replace(/%dir%/gi, 'right') ).addClass(PREVENT_CLOSE_CLASS); + + arrowLeft.click(function() { + mfp.prev(); + }); + arrowRight.click(function() { + mfp.next(); + }); + + mfp.container.append(arrowLeft.add(arrowRight)); + } + }); + + _mfpOn(CHANGE_EVENT+ns, function() { + if(mfp._preloadTimeout) clearTimeout(mfp._preloadTimeout); + + mfp._preloadTimeout = setTimeout(function() { + mfp.preloadNearbyImages(); + mfp._preloadTimeout = null; + }, 16); + }); + + + _mfpOn(CLOSE_EVENT+ns, function() { + _document.off(ns); + mfp.wrap.off('click'+ns); + mfp.arrowRight = mfp.arrowLeft = null; + }); + + }, + next: function() { + mfp.direction = true; + mfp.index = _getLoopedId(mfp.index + 1); + mfp.updateItemHTML(); + }, + prev: function() { + mfp.direction = false; + mfp.index = _getLoopedId(mfp.index - 1); + mfp.updateItemHTML(); + }, + goTo: function(newIndex) { + mfp.direction = (newIndex >= mfp.index); + mfp.index = newIndex; + mfp.updateItemHTML(); + }, + preloadNearbyImages: function() { + var p = mfp.st.gallery.preload, + preloadBefore = Math.min(p[0], mfp.items.length), + preloadAfter = Math.min(p[1], mfp.items.length), + i; + + for(i = 1; i <= (mfp.direction ? preloadAfter : preloadBefore); i++) { + mfp._preloadItem(mfp.index+i); + } + for(i = 1; i <= (mfp.direction ? preloadBefore : preloadAfter); i++) { + mfp._preloadItem(mfp.index-i); + } + }, + _preloadItem: function(index) { + index = _getLoopedId(index); + + if(mfp.items[index].preloaded) { + return; + } + + var item = mfp.items[index]; + if(!item.parsed) { + item = mfp.parseEl( index ); + } + + _mfpTrigger('LazyLoad', item); + + if(item.type === 'image') { + item.img = $('').on('load.mfploader', function() { + item.hasSize = true; + }).on('error.mfploader', function() { + item.hasSize = true; + item.loadError = true; + _mfpTrigger('LazyLoadError', item); + }).attr('src', item.src); + } + + + item.preloaded = true; + } + } + }); + + /*>>gallery*/ + + /*>>retina*/ + + var RETINA_NS = 'retina'; + + $.magnificPopup.registerModule(RETINA_NS, { + options: { + replaceSrc: function(item) { + return item.src.replace(/\.\w+$/, function(m) { return '@2x' + m; }); + }, + ratio: 1 // Function or number. Set to 1 to disable. + }, + proto: { + initRetina: function() { + if(window.devicePixelRatio > 1) { + + var st = mfp.st.retina, + ratio = st.ratio; + + ratio = !isNaN(ratio) ? ratio : ratio(); + + if(ratio > 1) { + _mfpOn('ImageHasSize' + '.' + RETINA_NS, function(e, item) { + item.img.css({ + 'max-width': item.img[0].naturalWidth / ratio, + 'width': '100%' + }); + }); + _mfpOn('ElementParse' + '.' + RETINA_NS, function(e, item) { + item.src = st.replaceSrc(item, ratio); + }); + } + } + + } + } + }); + + /*>>retina*/ + _checkInstance(); })); \ No newline at end of file diff --git a/assets/js/plugins/smooth-scroll.js b/assets/js/plugins/smooth-scroll.js new file mode 100644 index 000000000..c4179a731 --- /dev/null +++ b/assets/js/plugins/smooth-scroll.js @@ -0,0 +1,650 @@ +/*! + * smooth-scroll v16.1.2 + * Animate scrolling to anchor links + * (c) 2020 Chris Ferdinandi + * MIT License + * http://github.com/cferdinandi/smooth-scroll + */ + +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + define([], (function () { + return factory(root); + })); + } else if (typeof exports === 'object') { + module.exports = factory(root); + } else { + root.SmoothScroll = factory(root); + } +})(typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : this, (function (window) { + + 'use strict'; + + // + // Default settings + // + + var defaults = { + + // Selectors + ignore: '[data-scroll-ignore]', + header: null, + topOnEmptyHash: true, + + // Speed & Duration + speed: 500, + speedAsDuration: false, + durationMax: null, + durationMin: null, + clip: true, + offset: 0, + + // Easing + easing: 'easeInOutCubic', + customEasing: null, + + // History + updateURL: true, + popstate: true, + + // Custom Events + emitEvents: true + + }; + + + // + // Utility Methods + // + + /** + * Check if browser supports required methods + * @return {Boolean} Returns true if all required methods are supported + */ + var supports = function () { + return ( + 'querySelector' in document && + 'addEventListener' in window && + 'requestAnimationFrame' in window && + 'closest' in window.Element.prototype + ); + }; + + /** + * Merge two or more objects together. + * @param {Object} objects The objects to merge together + * @returns {Object} Merged values of defaults and options + */ + var extend = function () { + var merged = {}; + Array.prototype.forEach.call(arguments, (function (obj) { + for (var key in obj) { + if (!obj.hasOwnProperty(key)) return; + merged[key] = obj[key]; + } + })); + return merged; + }; + + /** + * Check to see if user prefers reduced motion + * @param {Object} settings Script settings + */ + var reduceMotion = function () { + if ('matchMedia' in window && window.matchMedia('(prefers-reduced-motion)').matches) { + return true; + } + return false; + }; + + /** + * Get the height of an element. + * @param {Node} elem The element to get the height of + * @return {Number} The element's height in pixels + */ + var getHeight = function (elem) { + return parseInt(window.getComputedStyle(elem).height, 10); + }; + + /** + * Escape special characters for use with querySelector + * @author Mathias Bynens + * @link https://github.com/mathiasbynens/CSS.escape + * @param {String} id The anchor ID to escape + */ + var escapeCharacters = function (id) { + + // Remove leading hash + if (id.charAt(0) === '#') { + id = id.substr(1); + } + + var string = String(id); + var length = string.length; + var index = -1; + var codeUnit; + var result = ''; + var firstCodeUnit = string.charCodeAt(0); + while (++index < length) { + codeUnit = string.charCodeAt(index); + // Note: there’s no need to special-case astral symbols, surrogate + // pairs, or lone surrogates. + + // If the character is NULL (U+0000), then throw an + // `InvalidCharacterError` exception and terminate these steps. + if (codeUnit === 0x0000) { + throw new InvalidCharacterError( + 'Invalid character: the input contains U+0000.' + ); + } + + if ( + // If the character is in the range [\1-\1F] (U+0001 to U+001F) or is + // U+007F, […] + (codeUnit >= 0x0001 && codeUnit <= 0x001F) || codeUnit == 0x007F || + // If the character is the first character and is in the range [0-9] + // (U+0030 to U+0039), […] + (index === 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039) || + // If the character is the second character and is in the range [0-9] + // (U+0030 to U+0039) and the first character is a `-` (U+002D), […] + ( + index === 1 && + codeUnit >= 0x0030 && codeUnit <= 0x0039 && + firstCodeUnit === 0x002D + ) + ) { + // http://dev.w3.org/csswg/cssom/#escape-a-character-as-code-point + result += '\\' + codeUnit.toString(16) + ' '; + continue; + } + + // If the character is not handled by one of the above rules and is + // greater than or equal to U+0080, is `-` (U+002D) or `_` (U+005F), or + // is in one of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to + // U+005A), or [a-z] (U+0061 to U+007A), […] + if ( + codeUnit >= 0x0080 || + codeUnit === 0x002D || + codeUnit === 0x005F || + codeUnit >= 0x0030 && codeUnit <= 0x0039 || + codeUnit >= 0x0041 && codeUnit <= 0x005A || + codeUnit >= 0x0061 && codeUnit <= 0x007A + ) { + // the character itself + result += string.charAt(index); + continue; + } + + // Otherwise, the escaped character. + // http://dev.w3.org/csswg/cssom/#escape-a-character + result += '\\' + string.charAt(index); + + } + + // Return sanitized hash + return '#' + result; + + }; + + /** + * Calculate the easing pattern + * @link https://gist.github.com/gre/1650294 + * @param {String} type Easing pattern + * @param {Number} time Time animation should take to complete + * @returns {Number} + */ + var easingPattern = function (settings, time) { + var pattern; + + // Default Easing Patterns + if (settings.easing === 'easeInQuad') pattern = time * time; // accelerating from zero velocity + if (settings.easing === 'easeOutQuad') pattern = time * (2 - time); // decelerating to zero velocity + if (settings.easing === 'easeInOutQuad') pattern = time < 0.5 ? 2 * time * time : -1 + (4 - 2 * time) * time; // acceleration until halfway, then deceleration + if (settings.easing === 'easeInCubic') pattern = time * time * time; // accelerating from zero velocity + if (settings.easing === 'easeOutCubic') pattern = (--time) * time * time + 1; // decelerating to zero velocity + if (settings.easing === 'easeInOutCubic') pattern = time < 0.5 ? 4 * time * time * time : (time - 1) * (2 * time - 2) * (2 * time - 2) + 1; // acceleration until halfway, then deceleration + if (settings.easing === 'easeInQuart') pattern = time * time * time * time; // accelerating from zero velocity + if (settings.easing === 'easeOutQuart') pattern = 1 - (--time) * time * time * time; // decelerating to zero velocity + if (settings.easing === 'easeInOutQuart') pattern = time < 0.5 ? 8 * time * time * time * time : 1 - 8 * (--time) * time * time * time; // acceleration until halfway, then deceleration + if (settings.easing === 'easeInQuint') pattern = time * time * time * time * time; // accelerating from zero velocity + if (settings.easing === 'easeOutQuint') pattern = 1 + (--time) * time * time * time * time; // decelerating to zero velocity + if (settings.easing === 'easeInOutQuint') pattern = time < 0.5 ? 16 * time * time * time * time * time : 1 + 16 * (--time) * time * time * time * time; // acceleration until halfway, then deceleration + + // Custom Easing Patterns + if (!!settings.customEasing) pattern = settings.customEasing(time); + + return pattern || time; // no easing, no acceleration + }; + + /** + * Determine the document's height + * @returns {Number} + */ + var getDocumentHeight = function () { + return Math.max( + document.body.scrollHeight, document.documentElement.scrollHeight, + document.body.offsetHeight, document.documentElement.offsetHeight, + document.body.clientHeight, document.documentElement.clientHeight + ); + }; + + /** + * Calculate how far to scroll + * Clip support added by robjtede - https://github.com/cferdinandi/smooth-scroll/issues/405 + * @param {Element} anchor The anchor element to scroll to + * @param {Number} headerHeight Height of a fixed header, if any + * @param {Number} offset Number of pixels by which to offset scroll + * @param {Boolean} clip If true, adjust scroll distance to prevent abrupt stops near the bottom of the page + * @returns {Number} + */ + var getEndLocation = function (anchor, headerHeight, offset, clip) { + var location = 0; + if (anchor.offsetParent) { + do { + location += anchor.offsetTop; + anchor = anchor.offsetParent; + } while (anchor); + } + location = Math.max(location - headerHeight - offset, 0); + if (clip) { + location = Math.min(location, getDocumentHeight() - window.innerHeight); + } + return location; + }; + + /** + * Get the height of the fixed header + * @param {Node} header The header + * @return {Number} The height of the header + */ + var getHeaderHeight = function (header) { + return !header ? 0 : (getHeight(header) + header.offsetTop); + }; + + /** + * Calculate the speed to use for the animation + * @param {Number} distance The distance to travel + * @param {Object} settings The plugin settings + * @return {Number} How fast to animate + */ + var getSpeed = function (distance, settings) { + var speed = settings.speedAsDuration ? settings.speed : Math.abs(distance / 1000 * settings.speed); + if (settings.durationMax && speed > settings.durationMax) return settings.durationMax; + if (settings.durationMin && speed < settings.durationMin) return settings.durationMin; + return parseInt(speed, 10); + }; + + var setHistory = function (options) { + + // Make sure this should run + if (!history.replaceState || !options.updateURL || history.state) return; + + // Get the hash to use + var hash = window.location.hash; + hash = hash ? hash : ''; + + // Set a default history + history.replaceState( + { + smoothScroll: JSON.stringify(options), + anchor: hash ? hash : window.pageYOffset + }, + document.title, + hash ? hash : window.location.href + ); + + }; + + /** + * Update the URL + * @param {Node} anchor The anchor that was scrolled to + * @param {Boolean} isNum If true, anchor is a number + * @param {Object} options Settings for Smooth Scroll + */ + var updateURL = function (anchor, isNum, options) { + + // Bail if the anchor is a number + if (isNum) return; + + // Verify that pushState is supported and the updateURL option is enabled + if (!history.pushState || !options.updateURL) return; + + // Update URL + history.pushState( + { + smoothScroll: JSON.stringify(options), + anchor: anchor.id + }, + document.title, + anchor === document.documentElement ? '#top' : '#' + anchor.id + ); + + }; + + /** + * Bring the anchored element into focus + * @param {Node} anchor The anchor element + * @param {Number} endLocation The end location to scroll to + * @param {Boolean} isNum If true, scroll is to a position rather than an element + */ + var adjustFocus = function (anchor, endLocation, isNum) { + + // Is scrolling to top of page, blur + if (anchor === 0) { + document.body.focus(); + } + + // Don't run if scrolling to a number on the page + if (isNum) return; + + // Otherwise, bring anchor element into focus + anchor.focus(); + if (document.activeElement !== anchor) { + anchor.setAttribute('tabindex', '-1'); + anchor.focus(); + anchor.style.outline = 'none'; + } + window.scrollTo(0 , endLocation); + + }; + + /** + * Emit a custom event + * @param {String} type The event type + * @param {Object} options The settings object + * @param {Node} anchor The anchor element + * @param {Node} toggle The toggle element + */ + var emitEvent = function (type, options, anchor, toggle) { + if (!options.emitEvents || typeof window.CustomEvent !== 'function') return; + var event = new CustomEvent(type, { + bubbles: true, + detail: { + anchor: anchor, + toggle: toggle + } + }); + document.dispatchEvent(event); + }; + + + // + // SmoothScroll Constructor + // + + var SmoothScroll = function (selector, options) { + + // + // Variables + // + + var smoothScroll = {}; // Object for public APIs + var settings, anchor, toggle, fixedHeader, eventTimeout, animationInterval; + + + // + // Methods + // + + /** + * Cancel a scroll-in-progress + */ + smoothScroll.cancelScroll = function (noEvent) { + cancelAnimationFrame(animationInterval); + animationInterval = null; + if (noEvent) return; + emitEvent('scrollCancel', settings); + }; + + /** + * Start/stop the scrolling animation + * @param {Node|Number} anchor The element or position to scroll to + * @param {Element} toggle The element that toggled the scroll event + * @param {Object} options + */ + smoothScroll.animateScroll = function (anchor, toggle, options) { + + // Cancel any in progress scrolls + smoothScroll.cancelScroll(); + + // Local settings + var _settings = extend(settings || defaults, options || {}); // Merge user options with defaults + + // Selectors and variables + var isNum = Object.prototype.toString.call(anchor) === '[object Number]' ? true : false; + var anchorElem = isNum || !anchor.tagName ? null : anchor; + if (!isNum && !anchorElem) return; + var startLocation = window.pageYOffset; // Current location on the page + if (_settings.header && !fixedHeader) { + // Get the fixed header if not already set + fixedHeader = document.querySelector(_settings.header); + } + var headerHeight = getHeaderHeight(fixedHeader); + var endLocation = isNum ? anchor : getEndLocation(anchorElem, headerHeight, parseInt((typeof _settings.offset === 'function' ? _settings.offset(anchor, toggle) : _settings.offset), 10), _settings.clip); // Location to scroll to + var distance = endLocation - startLocation; // distance to travel + var documentHeight = getDocumentHeight(); + var timeLapsed = 0; + var speed = getSpeed(distance, _settings); + var start, percentage, position; + + /** + * Stop the scroll animation when it reaches its target (or the bottom/top of page) + * @param {Number} position Current position on the page + * @param {Number} endLocation Scroll to location + * @param {Number} animationInterval How much to scroll on this loop + */ + var stopAnimateScroll = function (position, endLocation) { + + // Get the current location + var currentLocation = window.pageYOffset; + + // Check if the end location has been reached yet (or we've hit the end of the document) + if (position == endLocation || currentLocation == endLocation || ((startLocation < endLocation && window.innerHeight + currentLocation) >= documentHeight)) { + + // Clear the animation timer + smoothScroll.cancelScroll(true); + + // Bring the anchored element into focus + adjustFocus(anchor, endLocation, isNum); + + // Emit a custom event + emitEvent('scrollStop', _settings, anchor, toggle); + + // Reset start + start = null; + animationInterval = null; + + return true; + + } + }; + + /** + * Loop scrolling animation + */ + var loopAnimateScroll = function (timestamp) { + if (!start) { start = timestamp; } + timeLapsed += timestamp - start; + percentage = speed === 0 ? 0 : (timeLapsed / speed); + percentage = (percentage > 1) ? 1 : percentage; + position = startLocation + (distance * easingPattern(_settings, percentage)); + window.scrollTo(0, Math.floor(position)); + if (!stopAnimateScroll(position, endLocation)) { + animationInterval = window.requestAnimationFrame(loopAnimateScroll); + start = timestamp; + } + }; + + /** + * Reset position to fix weird iOS bug + * @link https://github.com/cferdinandi/smooth-scroll/issues/45 + */ + if (window.pageYOffset === 0) { + window.scrollTo(0, 0); + } + + // Update the URL + updateURL(anchor, isNum, _settings); + + // If the user prefers reduced motion, jump to location + if (reduceMotion()) { + window.scrollTo(0, Math.floor(endLocation)); + return; + } + + // Emit a custom event + emitEvent('scrollStart', _settings, anchor, toggle); + + // Start scrolling animation + smoothScroll.cancelScroll(true); + window.requestAnimationFrame(loopAnimateScroll); + + }; + + /** + * If smooth scroll element clicked, animate scroll + */ + var clickHandler = function (event) { + + // Don't run if event was canceled but still bubbled up + // By @mgreter - https://github.com/cferdinandi/smooth-scroll/pull/462/ + if (event.defaultPrevented) return; + + // Don't run if right-click or command/control + click or shift + click + if (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey) return; + + // Check if event.target has closest() method + // By @totegi - https://github.com/cferdinandi/smooth-scroll/pull/401/ + if (!('closest' in event.target)) return; + + // Check if a smooth scroll link was clicked + toggle = event.target.closest(selector); + if (!toggle || toggle.tagName.toLowerCase() !== 'a' || event.target.closest(settings.ignore)) return; + + // Only run if link is an anchor and points to the current page + if (toggle.hostname !== window.location.hostname || toggle.pathname !== window.location.pathname || !/#/.test(toggle.href)) return; + + // Get an escaped version of the hash + var hash; + try { + hash = escapeCharacters(decodeURIComponent(toggle.hash)); + } catch(e) { + hash = escapeCharacters(toggle.hash); + } + + // Get the anchored element + var anchor; + if (hash === '#') { + if (!settings.topOnEmptyHash) return; + anchor = document.documentElement; + } else { + anchor = document.querySelector(hash); + } + anchor = !anchor && hash === '#top' ? document.documentElement : anchor; + + // If anchored element exists, scroll to it + if (!anchor) return; + event.preventDefault(); + setHistory(settings); + smoothScroll.animateScroll(anchor, toggle); + + }; + + /** + * Animate scroll on popstate events + */ + var popstateHandler = function (event) { + + // Stop if history.state doesn't exist (ex. if clicking on a broken anchor link). + // fixes `Cannot read property 'smoothScroll' of null` error getting thrown. + if (history.state === null) return; + + // Only run if state is a popstate record for this instantiation + if (!history.state.smoothScroll || history.state.smoothScroll !== JSON.stringify(settings)) return; + + // Only run if state includes an anchor + + // if (!history.state.anchor && history.state.anchor !== 0) return; + + // Get the anchor + var anchor = history.state.anchor; + if (typeof anchor === 'string' && anchor) { + anchor = document.querySelector(escapeCharacters(history.state.anchor)); + if (!anchor) return; + } + + // Animate scroll to anchor link + smoothScroll.animateScroll(anchor, null, {updateURL: false}); + + }; + + /** + * Destroy the current initialization. + */ + smoothScroll.destroy = function () { + + // If plugin isn't already initialized, stop + if (!settings) return; + + // Remove event listeners + document.removeEventListener('click', clickHandler, false); + window.removeEventListener('popstate', popstateHandler, false); + + // Cancel any scrolls-in-progress + smoothScroll.cancelScroll(); + + // Reset variables + settings = null; + anchor = null; + toggle = null; + fixedHeader = null; + eventTimeout = null; + animationInterval = null; + + }; + + /** + * Initialize Smooth Scroll + * @param {Object} options User settings + */ + var init = function () { + + // feature test + if (!supports()) throw 'Smooth Scroll: This browser does not support the required JavaScript methods and browser APIs.'; + + // Destroy any existing initializations + smoothScroll.destroy(); + + // Selectors and variables + settings = extend(defaults, options || {}); // Merge user options with defaults + fixedHeader = settings.header ? document.querySelector(settings.header) : null; // Get the fixed header + + // When a toggle is clicked, run the click handler + document.addEventListener('click', clickHandler, false); + + // If updateURL and popState are enabled, listen for pop events + if (settings.updateURL && settings.popstate) { + window.addEventListener('popstate', popstateHandler, false); + } + + }; + + + // + // Initialize plugin + // + + init(); + + + // + // Public APIs + // + + return smoothScroll; + + }; + + return SmoothScroll; + +})); diff --git a/assets/js/vendor/jquery/jquery-3.4.1.js b/assets/js/vendor/jquery/jquery-3.4.1.js new file mode 100644 index 000000000..5b16efa11 --- /dev/null +++ b/assets/js/vendor/jquery/jquery-3.4.1.js @@ -0,0 +1,10598 @@ +/*! + * jQuery JavaScript Library v3.4.1 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2019-05-01T21:04Z + */ +( 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 document = window.document; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var concat = arr.concat; + +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. + return typeof obj === "function" && typeof obj.nodeType !== "number"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + + + + 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.4.1", + + // 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 ); + }, + + // Support: Android <=4.0 only + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; + +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 ); + }, + + 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 global context + globalEval: function( code, options ) { + DOMEval( code, { nonce: options && options.nonce } ); + }, + + 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; + }, + + // Support: Android <=4.0 only + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // 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 concat.apply( [], 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.4 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2019-04-08 + */ +(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, + push_native = 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]", + + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", + + // 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-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + 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 + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.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 ) { + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + 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. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && rdescend.test( selector ) ) { + + // 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 + " " + toSelector( groups[i] ); + } + newSelector = groups.join( "," ); + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + } + + 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.namespaceURI, + docElem = (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 + 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 + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + 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 ); + } + } + + /* 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 ) { + // 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("~="); + } + + // 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(".#.+[+~]"); + } + }); + + 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" ); + } + + // 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 + 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 + if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + 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 ) { + return a === document ? -1 : + b === document ? 1 : + 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 + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + 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 + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + 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 += ""; + + 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; + }; + }, + + "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 ) { + 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 ) { + 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; + 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 ( typeof elem.contentDocument !== "undefined" ) { + 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 master Deferred + master = 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 ) ) { + master.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( master.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return master.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); + } + + return master.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"; + }; + +var swap = function( elem, options, callback, args ) { + 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.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + + + +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 ); + + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // Support: IE <=9 only + option: [ 1, "" ], + + // 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, "", "" ] +}; + +// Support: IE <=9 only +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + + +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; +} + + +( 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; +} )(); + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + 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 ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + 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 = {}; + } + 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 ) { + + // Make a writable jQuery.Event from the native event object + var event = jQuery.event.fix( nativeEvent ); + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + handlers = ( dataPriv.get( this, "events" ) || {} )[ 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(); + return 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: function( event ) { + var button = event.button; + + // Add which for key events + if ( event.which == null && rkeyEvent.test( event.type ) ) { + return event.charCode != null ? event.charCode : event.keyCode; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { + if ( button & 1 ) { + return 1; + } + + if ( button & 2 ) { + return 3; + } + + if ( button & 4 ) { + return 2; + } + + return 0; + } + + return event.which; + } +}, 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; + }, + + 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 + + /* eslint-disable max-len */ + + // See https://github.com/eslint/eslint/issues/3229 + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, + + /* eslint-enable */ + + // 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, pdataCur, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.access( src ); + pdataCur = dataPriv.set( dest, pdataOld ); + events = pdataOld.events; + + if ( events ) { + delete pdataCur.handle; + pdataCur.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 = concat.apply( [], 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" ) + } ); + } + } 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.replace( rxhtmlTag, "<$1>" ); + }, + + 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 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, + 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; + } + } ); +} )(); + + +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"; + } + + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + // Support: IE 9-11 only + // Also use offsetWidth/offsetHeight for when box sizing is unreliable + // We use getClientRects() to check for hidden/disconnected. + // In those cases, the computed value can be trusted to be border-box + if ( ( !support.boxSizingReliable() && isBorderBox || + val === "auto" || + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + 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 && type !== false ) { + 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" ) || {} )[ 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() { + var doc = this.ownerDocument || 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, + 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 = Date.now(); + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml; + 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 ) { + xml = undefined; + } + + if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + 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++ ) + 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 ); + } + + // 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._evalUrl = function( url, options ) { + 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 ); + } + } ); +}; + + +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( " + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + +

Here’s a test of Bigfoot.js, a rather awesome addition to the web. 1 (edit: It’ll remain elusive, see footnote #2.)2 (edit № 2: I’ve gotten it to work, as of 2015-05-31! It wasn’t an issue with Jekyll or GitHub Pages, but rather with my understanding of how Jekyll & GitHub plugins work. Once I realized that, it just took some more tinkering to get the appropriate JavaScript calls and SCSS things working.)

+ +

Sooner or later I’ll write about how I’ve made this site so far. I would still like to add two main things to it:

+ +
    +
  • the Bigfoot.js inline footnote functionality @done(2015-05-31)!
  • +
  • an alternate stylesheet in the vein of Brett Terpstra’s SuperReadable.
  • +
+ +

Terpstra’s alternate stylesheet hides under a gear in the top right corner of his site, and allows visitors to switch to a stylesheet that uses OpenDyslexic, a free and open source font designed for dyslexic readers. (They might not speak up, but you’ve got students, users, or patrons who’d appreciate being told about OpenDyslexic in your syllabi or other handouts.)

+ +

The process of making this site with Jekyll has been a rewarding foray into using the command line interface, but it initially took quite a bit longer than I’d hoped. So I anticipate creating a brief series of “how-to” posts from my old process notes as I was putting this together. Jekyll’s a great blogging alternative to WordPress that uses fewer resources (i.e. doesn’t require a database) and can be hosted for free on GitHub pages, making it great for LibSchool students who want to create a site that will be a bit more of a learning opportunity.

+ +

For now, here’s a list of links I’d recommend for learning about Jekyll:

+ +
    +
  1. Trevor Jones has written probably the best guide I’ve seen so far to setting up a Jekyll/GitHub Pages blog—I wish I’d have found this when I was putting my own site together.
  2. +
  3. Michael Rose’s “Going Static” helps explain why to use Jekyll.
  4. +
  5. Mike Greiling’s “Jekyll From Scratch” helped me get through starting my own.
  6. +
  7. Barry Clark’s “Build a Blog with Jekyll and GitHub Pages” also helps distinguish Jekyll from alternatives like WordPress.
  8. +
+ +

If you have questions about making a site of your own using Jekyll—or any of this, really—don’t be shy about contacting me on Twitter.

+ +
+
    +
  1. +

    You can find this arcane, hirsute magick here courtesy of Chris Sauvé, a Canadian otherwise known as lemonmade

    +
  2. +
  3. +

    After an afternoon of tweaking, tinkering, asking questions, and reading specifications sheets, it seems that Bigfoot.js won’t work with Kramdown, the parser that Github pages uses to convert Markdown into html. It comes down to Bigfoot needing the footnote definitions list items to have a class="footnote" attribute, but there doesn’t seem to be a way to make this happen with Kramdown. As awesome as Bigfoot.js appears, it will remain elusive around here until this aspect of Kramdown syntax changes or I decide to do a fundamental overhaul of how I make my site. I’m adding this edit so that this can be useful to anyone else hoping to make Bigfoot.js work with Jekyll and to anyone heartened by seeing others tinker and fail. 

    +
  4. +
+
+ + + + +
+ +
+ + + + + + + + + + + +

+ Tags: + + + , + + + + +

+ + + + + + +
Created:
+ + +
Updated:
+ +
+ + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/blips/introducing-blips-and-link-rhizomes.html b/blips/introducing-blips-and-link-rhizomes.html new file mode 100644 index 000000000..f6855d137 --- /dev/null +++ b/blips/introducing-blips-and-link-rhizomes.html @@ -0,0 +1,685 @@ + + + + + + +Introducing Blips and Link Rhizomes — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + + + +

Here We Go, What’s Our Scenarios?

+ +

Blips

+ +

Blog posts feel to me like they should involve a few paragraphs, and probably shouldn’t happen more than once a day. Maybe just a few a week is what feels right for them on my own site. (This feeling is just for my own writerly headspace, not a feeling about how others should conceive of posts on their sites!) I’m looking for something in between this more considered blog post and a thought I’d put on a microblogging site like Mastodon, and one that will play nicely with RSS, unlike the “meant to be revised continually” notes in my digital garden.

+ +

Therefore, I’m trying out this separate category of posts, for things that can be as off-the-cuff as Jekyll allows, including multiple a day. Let’s see where this takes us!

+ +

I’ve also reflecting on the fact that I’ve added a fair number of things in the notes section since 2020, which is the last time I wrote a blog post—and so to RSS feedss, nothing has happened in that whole time. So I’m thinking I might also start making a new blogpost whenever I add a note, or at least make round-up posts of “these are recently added notes.” Either of these mean that notes will show up in RSS feeds once, but not automatically re-appear with each revision.

+ + + +

As I’ve been tinkering with this site this holiday break, I noticed that the links in the sidebar author profile had grown unruly and could stand a very substantial pruning. Alongside this, I’ve also noticed people using Linktree, Link Me, and similar services for sharing “hey! I’m also over here!” in a centralized space.

+ +

So I figured I’d move the trimmed links into a new page, using that “other places I exist online” link page pattern.

+ +

However, I wanted to follow something like the POSSE principle, where I publish (on my) own site and share elsewhere, rather than relying on other services that can easily go the way of the dodo Twitter.

+ +

Putting this together with my fondness of Dave Cormier’s repeated use of rhizome metaphors (as well as uses of that metaphor by other folks, like Deleuze & Guattari), it dawned on me that “rhizome” would be a great name for this pattern.

+ +

And thus, links rhizome sprouted up.

+ +

Conclusions That Don’t Conclude

+ +

Adding the “blip” category will give this site a current total of five categories:

+
    +
  • blips (for smaller posts)
  • +
  • blog (for what I think of as blog posts; I’ll need to add this retroactively to most current posts, I think)
  • +
  • weekly assemblages (weekly linkpost roundups)
  • +
  • monthly signal boosts (monthly linkpost roundups)
  • +
  • notes (on whatever interval)
  • +
+ +

That seems quite workable for the moment. And as is nice about most things online, it can be revised as necessary.

+ +

I’d also be quite glad for people interested in managing their own link rhizomes instead of using hosted services to use the links-rhizome pattern.

+ +

For those of us who already have websites, it’s one more way to take a sort of POSSE approach: “Publish on your Own Site, Share Elsewhere.”

+ +

Onwards!

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

+ Categories: + + + + + +

+ + + + +
Created:
+ + +
+ + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/blips/phone-to-blog-blip-workflow.html b/blips/phone-to-blog-blip-workflow.html new file mode 100644 index 000000000..80260c659 --- /dev/null +++ b/blips/phone-to-blog-blip-workflow.html @@ -0,0 +1,693 @@ + + + + + + +Phone to Blog Blip Workflow — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + + + +

Couch to Internet

+ +

With a cat snoozing on my lap and less than 10 minutes before I’m supposed to start watching a new-to-me episode of Star Trek: The Next Generation, the thought occurred to me: how quickly could I make a blog post happen?

+ +

Long ago I set up Working Copy on my iPhone. It’s an app that helps you handle a Git repository. If I recall correctly, I set it up as an extra “safety net” for giving presentations using Reveal; I wanted to make sure I had a way to fix typos or other last-minute edits.

+ +

Now I’m instead trying to see whether this app could be repurposed as an POSSE-mindset alternative to Mastodon or other microblogging platforms.

+ +

It’s been 10 minutes! Let’s commit this!

+ +

Edit, After the Episode

+ +

Here’s a Mastodon post I made minutes after publishing the above:

+ +

With more practice, I’m certain I could make this go more quickly. These 10 minutes included trying to figure out what I’d write about, plus re-familiarizing myself with how Working Copy actually works.

+ +

I spent a few minutes looking in Textastic, a text editor app. Instead, it was easiest to:

+
    +
  • make the new file with Working Copy
  • +
  • copy and paste the relevant front matter from another post in the same category
  • +
  • edit the front matter
  • +
  • actually write
  • +
  • save and commit
  • +
+ +

Then I had to wait about 3 to 5 minutes for GitHub to process that commit and turn it into a published page.

+ +

It might sound closer to a Rube Goldberg machine than fully automated queer space blogging, but it’s a workable solution for a mostly-POSSE approach to blogging.

+ +

And I still have the cat snoozing on my lap!

+ +

Summary

+ +

Overall, this seems like a pretty useful alternative to posting longer thoughts on Mastodon or other social media.

+ +

There’s probably an extra 5-ish minutes of work involved.

+ +

This 5 minutes of labor (not 5 “real-time” minutes) includes:

+ +
    +
  • set-up (generating the new file with appropriate lines of YAML)
  • +
  • file management (committing and pushing the new file to GitHub),
  • +
  • then (after waiting a few minutes outside of these “5-ish” ones for GitHub to process and publish the new file), getting the URL to share in Mastodon and actually sharing it.
  • +
+ +

So this is clearly somewhat more involved than just posting a routine idea or thread on Mastodon. But it’s a workable alternative!

+ +

Some thoughts (or other purposes) might well be worth that 5-ish minutes of labor. (And yes, for those following closely: even after that episode and all these edits, the cat is still snoozing away on my lap.)

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

+ Categories: + + + + + +

+ + + + +
Created:
+ + +
+ + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/blog/new-directions-in-information-fluency.html b/blog/new-directions-in-information-fluency.html new file mode 100644 index 000000000..aff02e257 --- /dev/null +++ b/blog/new-directions-in-information-fluency.html @@ -0,0 +1,670 @@ + + + + + + +New Directions in Information Fluency — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + +


+On April 4th & 5th, I drove up to Augustana College in Rock Island, Illinois with my friend & colleague Katherine Ahnberg for the New Directions in Information Literacy conference at Augustana College.

+ +

As Katherine recently wrote, we presented a brief history of humanities computing (digital humanities or DH), an overview of how DH often interfaces with libraries, and demonstrated a number of easily-adopted tools that reference librarians might recommend to students/researchers curious about what computing approaches can do for humanities inquiry. This primer, along with our slides, are hosted at dhreadyreference on GitHub.1 We may go back and annotate or expand the entries, but for anyone curious about digital humanities and libraries, or tools with low learning curves, I hope this provides a useful introduction.

+ +

Should you find it useful—or should you like to add things or ask for clarification—feel free to get in touch.

+ +
+
    +
  1. +

    We specifically chose to put it on GitHub because, as graduate students, we knew we’d have access to it beyond our years at IU-Bloomington. On top of that, we wanted to demonstrate the relative ease with which it can be used as a repository for these sorts of things. 

    +
  2. +
+
+ + + + +
+ + + + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/browserconfig.xml b/browserconfig.xml new file mode 100644 index 000000000..b3930d0f0 --- /dev/null +++ b/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #da532c + + + diff --git a/categories/index.html b/categories/index.html new file mode 100644 index 000000000..8f75d7647 --- /dev/null +++ b/categories/index.html @@ -0,0 +1,3730 @@ + + + + + + +Posts by Category — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + +
+ + + + + +
+ +

Posts by Category

+ + + + + + + +
    + + + + + +
  • + + weekly-assemblage 39 + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + notes 19 + +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + monthly-signal-boost 3 + +
  • + + + + + + + + + + + + + + + + + +
  • + + blips 2 + +
  • + + + + + +
  • + + blog 1 + +
  • + + + + + + + + + + + +
+ + + + + + + +
+

weekly-assemblage

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

+ + WA 2017 Week 09: Badges, Type, BibTeX + + +

+ + +

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

+ + +

Briefly linking to Emily Ford’s article about badges, a short reference about using type on the web, and getting going with a bibliography tool. +

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

+ + WA 2016 Week 31: Design Things Galore + + +

+ + +

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

+ + +

Design thinking in Idaho libraries, button templates from Librarian Design Share and Char Booth, and a few minor site font updates. +

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

+ + WA 2016 Week 17: Research Notebook is Go! + + +

+ + +

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

+ + +

Much like with succulents, I’ve planted an offshoot of this blog to see whether it’ll take root. Open Humanities Research Notebooks—come and join the future™. +

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

+ + WA 2016 Week 12: DERAIL, Site Updates + + +

+ + +

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

+ + +

DERAIL 2016 student forum at Simmons! Also site updates — recommended readings pages and deep links with Anchor.js. +

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

+ + WA 2016 Week 07: Tools for Thinking + + +

+ + +

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

+ + +

Tools for Thinking (for information literacy instruction) and Tech Tools for Keeping Thoughts in Order (using Atom and its packages) +

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

+ + WA 2016 Week 04: Library Privacy + + +

+ + +

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

+ + +

Library privacy session with ACLU Idaho’s Ritchie Eppink and Library Freedom Project’s Alison Macrina at Meridian Library District’s unBound technology lab. +

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

+ + WA 2016 Week 02: Giroux on Neutrality + + +

+ + +

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

+ + +

A culture of positivism, distinguishing between objectivity and objectivism, hegemony, false neutrality, values—this article has all sorts of relevance for l...

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

+ + Weekly Whaaa…? + + +

+ + +

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

+ + +

Why weekly? Why assemblage? Why Fluxus? And what’s that “sous les pavés, la plage” thing about? +

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

+ + WA 2015 Week 48 Fister, Kurz, Vecchione + + +

+ + +

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

+ + +

Unanticipated Costs of “Doing More with Less”; Be Yr Own Her@; Making It Known that Libraraies are Spaces for Making +

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

+ + WA 2015 Week 47 Schoofs and Battista + + +

+ + +

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

+ + +

Articles from LOEX Quarterly (one by Schoofs, another by Battista) that look at learning beyond the library’s space. +

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

+ + WA 2015 Week 46 Massumi and North + + +

+ + +

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

+ + +

Enthusiasm about Massumi putting Deleuze in a nutshell! Analogies between the pedagogy & structural place of Writing Centers & libraries! Jekyll on t...

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

+ + Weekly Assemblage 2015 Week 45 + + +

+ + +

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

+ + +

Three links & lots of enthusiasm! Elmborg’s “Literacies Large and Small,” a Time Management mega post, & how STEM relates to the liberal arts. +

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

+ + Weekly Assemblage 2015 Week 44 + + +

+ + +

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

+ + +

Halloween at CWI Library (Once Upon a Time); Readings I’m looking forward to; Taught my first library resources session. +

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

+ + Weekly Assemblage 2015 Week 43 + + +

+ + +

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

+ + +

A #critlib chat on gender & leadership in LIS, plus some history links. +

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

+ + Weekly Assemblage 2015 Week 42 + + +

+ + +

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

+ + +

Live! Real! Humans! (in the Classroom); Code Camps, the “Californian Ideology,” & Higher Ed’s Purpose; Open Access & “The Library of Forking Paths.” +

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

+ + Weekly Assemblage 2015 Week 41 + + +

+ + +

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

+ + +

Talking about librarianship values: objectivity as a value and valuing inclusivity enough to work toward it in earnest. And again—sorry, Eduardo. +

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

+ + Weekly Assemblage 2015 Week 40 + + +

+ + +

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

+ + +

Starting at the College of Western Idaho & going to the Idaho Library Association 2015 Annual Conference! +

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

+ + Weekly Assemblage 2015 Week 39 + + +

+ + +

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

+ + +

Getting library cards and appreciating some unexpected aspects of Maria Accardi’s Feminist Pedagogy for Library Instruction. +

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

+ + Weekly Assemblage 2015 Week 38 + + +

+ + +

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

+ + +

Driving from Bloomington, Indiana to Boise, Idaho; Luciano Floridi’s Information: A Very Short Introduction. +

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

+ + Weekly Assemblage 2015 Week 37 + + +

+ + +

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

+ + +

A #critlib chat on information & migrant populations; threats to the Tor exit node in Kilton Public Library; CFP for papers on whiteness in LIS; study on...

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

+ + Weekly Assemblage 2015 Week 36 + + +

+ + +

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

+ + +

Reflections on the second #radlibchat and a Library Freedom Presentation by Alison Macrina. +

+
+
+ + +
+ Back to top ↑ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

notes

+
+ + + + + +
+
+ +

+ + Obsidian Tasks patterns + + +

+ + +

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

+ + +

How I use the Tasks plugin for Obsidian. +

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

+ + I’ve Been Using Obsidian + + +

+ + +

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

+ + +

I’ve been using Obsidian. Both enthusiastically and reluctantly. +

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

+ + New note on Snippets and VS Code + + +

+ + +

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

+ + +

Type similar things often? Here are some snippets you can use in VS Code. +

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

+ + New note on Rhetorical Précis + + +

+ + +

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

+ + +

Looking for a succinct note-taking format? Try a rhetorical précis! +

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

+ + New note on Jekyll Guides + + +

+ + +

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

+ + +

Note linking to some useful Jekyll guides. +

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

+ + New note on Mastodon Settings + + +

+ + +

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

+ + +

Looking to understand some Mastodon settings? Here are my own settings. +

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

+ + New note on Mastodon iOS apps + + +

+ + +

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

+ + +

Looking for iOS apps for Mastodon? Here’s a few I recommend. +

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

+ + New note on the VS Code editor + + +

+ + +

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

+ + +

Looking for a nice code or text editor? Here’s why I like VS Code. +

+
+
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + +
+ Back to top ↑ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

monthly-signal-boost

+
+ + + + + +
+
+ +

+ + August 2020 Monthly Signal Boost + + +

+ + +

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

+ + +

Mindfulness with the Waking Up and Plum Village apps; Most excellent tunes from Sonic D and Autodidact +

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

+ + July 2020 Monthly Signal Boost + + +

+ + +

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

+ + +

Organizing Ideas Podcast; The Latino Card; Tricycle Magazine; etc. +

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

+ + Introducing Monthly Signal Boosts + + +

+ + +

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

+ + +

Monthly signal boosts will be short reflections on what I’ve read, listened to, watch, etc. +

+
+
+ + +
+ Back to top ↑ +
+ + + + + + + + + + + + + + + + + +
+

blips

+
+ + + + + +
+ +
+ + + + + + +
+ +
+ + +
+ Back to top ↑ +
+ + + + + +
+

blog

+
+ + + + + +
+
+ +

+ + New Directions in Information Fluency + + +

+ + +

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

+ + +

Brief reflections on a talk about bringing digital humanities to the reference desk, which I co-presented with Katherine Ahnberg at the New Directions in Inf...

+
+
+ + +
+ Back to top ↑ +
+ + + + + + + + + + + + +
+
+
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/colophon/index.html b/colophon/index.html new file mode 100644 index 000000000..87ca41e23 --- /dev/null +++ b/colophon/index.html @@ -0,0 +1,526 @@ + + + + + + +Colophon — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + +
+ + ryan’s pocket notebooks with cute stickers on their covers + + +
+ + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+
Colophon
+
historical A statement at the end of a book, typically with a printer’s emblem, giving information about its authorship and printing. OED
+
+ +

When you find yourself wondering, “how does one make something like this?,” it’s a good time to look for a colophon. If you make something cool, consider letting others know how.

+ +

This Very Site

+ +

This page is built with Jekyll, currently hosted on GitHub Pages, and looks like this under the hood. It uses Michael Rose’s Minimal Mistakes theme, with a few of my own modifications.1

+ +

Jekyll and GitHub Pages make for a great alternative to WordPress if you’re looking for more control, want to learn more about what is going on behind the magic, or just plain don’t want to pay for hosting while you’re a student or emerging scholar/professional. If those things resonate, I suggest you check out Building a static website with Jekyll and GitHub Pages and Running a Collaborative Research Website and Blog with Jekyll and GitHub, which are a great pair of introductions to how you might use it.2

+ +

To the Minimal Mistakes theme, I’ve added Bigfoot.js for the fancy pop-up footnotes, Reveal.js for a splendid presentation alternative to PowerPoint or Keynote, FontAwesome for most of the icons, and James Walsh’s Academicons to supplement Font Awesome with the Open Access lock, Academia-dot-edu, Orcid, and Zotero icons.

+ +

I’ve also added (and minimally customized) Maxime Vaillancourt’s Bidirectional links generator to make bidirectional links work in my Notes/Digital Garden.

+ +

The favicon (the little ellipsis in a speech bubble) is “Blog” by Scott Lewis, available with a CC BY-3.0 license from the Noun Project. I chopped and screwed cropped and shrank it into the favicon format.

+ + + +

Whenever possible, I link to WorldCat records for books. Why not work to make library access a default practice?

+ +

Writing Formats

+ +

I’m a big fan of using Markdown wherever possible. It’s the primary source code for this site, for instance. I constantly use it with Obsidian and VS Code for all sorts of notetaking, as I explain a bit further below. I also use it with Pandoc for academic writing.

+ +

If you’re curious about using Markdown with Pandoc, I’d recommend this Programming Historian guide.

+ +

Amanda Visconti’s guide to Markdown and Jekyll at the Programming Historian provides an excellent starting point as well.

+ + + +

Journaling and Attention Management

+ +

For keeping my mental lines of flight somewhat directed, I use text files that blend blend Ryder Carroll’s “Rapid Logging” Bullet Journal system with aspects of Francesco Cirillo’s Pomodoro Technique.

+ +

I used to create monthly files for this when I did this in the Atom text editor. Now I make daily notes in Obsidian. I’ll be detailing how in this series of notes.

+ +

I explain the monthly version of this system further in my GitHub repo for my monthly planning files, which you’re very welcome to download and adapt for your own brain. I’ll eventually update this guide to match what I do with Dendron.

+ +

It’s not a fully-featured project management system with active reminders, of course. For that I’ve used OmniFocus in the past, but currently do this mostly through a combination of text notes, calendar reminders, and regular reviews of my notes.

+ +

Notekeeping & Text Editor Programs

+ +

Obsidian has largely replaced Dendron as my notes app, due almost exclusively to the amazing Tasks plugin.

+ +

VS Code has been my text and code editor of choice since about 2020, when I switched over from Atom. VS Code doesn’t cost any money, and you can customize it with themes and extensions galore, in addition to customizing your settings.

+ + + +

Daybreak has become the theme I like using wherever I can. It’s dark and warm, and it provides syntax-based color changes for relevant parts of Markdown, HTML, CSS, and the few other languages I dabble in. (More specifically, I use either the Daybreak Italic or Daybreak Bold variants most of the time.) Daybreak is a variant of Horizon, which unfortunately doesn’t have an official theme extension for VS Code anymore as of mid-2022.

+ + +
+
    +
  1. +

    Michael Rose has a page about his various free, open source Jekyll themes in case you’d like to see others. 

    +
  2. +
  3. +

    I’ll eventually make a separate post about all this, but until I do, here’s a bunch of other useful links for Jekyll things. Michael Rose’s “Going Static”, Mike Greiling’s “Jekyll From Scratch”, & Barry Clark’s “Build a Blog with Jekyll and GitHub Pages” all do the job of introducing Jekyll admirably. Carl Boettinger’s “Learning Jekyll” and W. Caleb McDaniel’s “Open Notebook History” each show how Jekyll- or Git-based sites work well for scholarly notebooks. I believe I initially taught myself from Trevor Jones’s series of posts on setting up a Jekyll/GitHub Pages blog and Mike Greiling’s post “Jekyll from Scratch”, but at this point, I can’t really remember. 

    +
  4. +
+
+ + + + +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/critical-reflection.html b/critical-reflection.html new file mode 100644 index 000000000..0f1686f6a --- /dev/null +++ b/critical-reflection.html @@ -0,0 +1,699 @@ + + + + + + +Critical Reflection #critlib chat — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + + + +

Here’s a post in preparation for the “Critical Reflection” #critlib chat moderated by Lisa Hubbell.

+ +

Lisa Hubbell’s commitment to making this chat about critical reflection more accessible to people for whom Twitter isn’t optimal inspired me enough to want to do a “seeding” blog post of my own. The topic itself seems to beg for a different kind of engagement. I’ve got a few different facets of “reflection” in mind, so I’ll try to address all of them here.

+ +

Tools for Thinking

+ +

Prompts work well for me, as do other tools for thinking.

+ +

The most basic of these prompts was drilled into me while I was on high school newspaper, if not earlier: the old, reliable “who, what, when, where, why, and how?” questions.

+ +

Here’s a few more that I believe help nuance those and make our answers more critically reflective:1

+ +
    +
  • For whom is this accurate, in what ways, and under what conditions?
  • +
  • Who does this obscure?
  • +
  • Whose participation is left out?
  • +
  • Does this way of thinking frame people as passive or active?
  • +
  • How is this useful? What does it help us do in the world?
  • +
+ +

David Seah’s various productivity tools profoundly help reinforce a practice of reflection. Unlike a lot of people who write about productivity, his site and tools don’t trip my spidey sense for boosterism or selling things. He gives the documents away as free downloads! (He does sell pre-printed ones as well.) Instead, between his explanations of the various tools and his own blog about things like his “groundhog resolutions”, he seems very committed to the idea that review is a (maybe the?) path to progress.

+ +

I like Seah’s phrase “tools for thinking” enough that it’s what I call most of the relevant library handouts I make at my library: simple templates for expanding & narrowing search terms, for brainstorming keywords, that kind of thing.

+ +

My Actual Practice

+ +

For readings, I take lots of marginal notes. This semester I read Casey Boyle’s …something like a reading ethics…, and I intend to start doing something along those lines from here on out.

+ +

My reading notes—and all of my notes, really—are plain text, in Markdown format, and stored in Dropbox. That way I can always sync them between whatever computer or device I’m using. I usually use Atom on my laptop or at work, plus Editorial on my phone.

+ +

Plain text synced through Dropbox means that I don’t have to fret about leaving a notebook filled in my insights somewhere. I profoundly enjoy writing by hand, but I don’t enjoy the anxiety that builds up the more I have in a notebook and nowhere else. When I want to go back and somehow do revisions on earlier ideas in plain text, I’ll usually use Critic Markup for most of my jotting-ideas-down writing, or much more rarely I’ll track changes for more formal writing through Git.

+ +

I also have a sort of bullet journal with plain text files for each month, with the idea that I’ll go back and do some review every night as well as again on weekends. It helps, but I certainly don’t do it as consistently as I’d like.

+ +

The Pomodoro technique (and time-blocking more generally) also sometimes helps when I need extra push to focus on something that I know I also want to examine critically. Pomodoros seem to give me permission to toggle between the “make stuff!” and “wait, what’s this leading toward?” habits of mind. Beyond just each 30 minute cycle (25 minutes of GO!!!!!, 5 minutes reflection), the broader technique also invites more substantive reflection every few hours and at the beginning & end of the day. I’m not great with experiencing time, and therefore really not great at estimating time. Since pomodoros turn nicely into time tracking, it’s a practice with many interlocking benefits.2

+ +

My Desired Practice

+ +

Since Lisa Hubbell’s second “seeding” post for this critlib chat delves into broader teachings and reflective practices, I’ll mention that Buddhist thought has worked well for me since about high school. I wouldn’t claim to be a practicing Buddhist and don’t really identify as one, just as sort of a long-time beginner or appreciator; I don’t go to a regular meeting place, don’t have a consistent meditation practice, and couldn’t recall the details of the noble eightfold path or any other fundamental precepts off the top of my head. All the same, Buddhist teachings around liberation, loving kindness, and mindfulness more than merely resonate with me. They help me make sense of the world. They work for me, and they’ve worked for other people I care about deeply.

+ +

I’ve found helpful things in writings by bell hooks (that’s to her posts at Lion’s Roar magazine/website, although my introduction to her Buddhism was the “Agent of Change” article for which Tricycle occasionally lifts its paywall), Shunryu Suzuki’s Zen Mind, Beginner’s Mind, Brad Warner’s Hardcore Zen, and Chade-Meng Tan’s endearingly self-deprecating Search Inside Yourself.3

+ +

Years ago, when I desperately needed to hear something along its lines, the Back to Work “The Second Arrow” episode on ADD, Buddhism, and mindfulness was profoundly helpful, too.

+ +

For a critlib audience? I really, really recommend listening to this “Talking Race, Love, and Liberation” episode of the Buddhist Geeks podcast.4 The dialog between the host & Reverend angel Kyodo williams captures the sort of liberation-seeking, loving kindness practice that I’m working toward making my own critical reflective practice.

+ +
+
    +
  1. +

    I don’t recall seeing these anywhere in particular; they’re sort of a distillation of what I’ve picked up from various types of what I consider “critical theory,” ranging from Cultural Studies to various types of activism to rhetorical analysis. 

    +
  2. +
  3. +

    If you want to get next-level geeky with this, Ugo Landini’s Pomodoro app for Mac can sync up with Growl notifications and then even to your phone with Prowl notifications. Time’s passage can follow you even when you wander away from your keyboard, as long as you carry your phone with you. If you’re like me, you’ll be humbled by how rapidly & repeatedly your monkey mind runs away from your intentions. 

    +
  4. +
  5. +

    I feel I’m obligated to also gesture toward whatever second-hand Alan Watts books I read back in high school, but I suspect they’d strike me as pretty Orientalist if I re-read them now. Choose your own adventure with those. Looking at titles & cover images, it probably included The Way of Zen and This is It

    +
  6. +
  7. +

    It has enough Buddhist terminology that I occasionally felt more like an eavesdropper than a listener, but I kind of feel like that’s an especially productive approach to this topic. It’s good practice to sit with not being centered by a conversation. 

    +
  8. +
+
+ + + + +
+ + + + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/critlib-chatty-critical-librarianship-on-twitter.html b/critlib-chatty-critical-librarianship-on-twitter.html new file mode 100644 index 000000000..9e9530313 --- /dev/null +++ b/critlib-chatty-critical-librarianship-on-twitter.html @@ -0,0 +1,630 @@ + + + + + + +#critlib Chatty Critical Librarianship on Twitter — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + +

Here’s a post I wrote for Hack Libary School on critical librarianship and the #critlib chats on Twitter. I also discuss student-led interests groups, metacognition, and Bloom’s Taxonomy of educational objectives. There’s even a brief bibliography of anthologies to check out for more on critical librarianship.

+ + + + +
+ + + + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/critlib-feelings.html b/critlib-feelings.html new file mode 100644 index 000000000..d611274b3 --- /dev/null +++ b/critlib-feelings.html @@ -0,0 +1,673 @@ + + + + + + +critlib #feelings — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + + + +

This is a post for the upcoming #critlib chat: “#feelings”.

+ +

Why are you a critical librarian?

+ +

Libraries exist as spaces for transformation and change. Without being convinced about the effects of library access on his own life, Andrew Carnegie almost certainly wouldn’t have helped fund so many libraries with free public service and open stacks plans that encourage direct access, browsing, and discoverability.1

+ +

As spaces for transformation, libraries are not intended to be neutral. They have been funded, built, and organized with particular outcomes in mind.

+ +

I’m a critical librarian because it is important—both for patrons and for myself—for me to recognize that libraries have never been neutral, then do the difficult and sometimes uncomfortable work of uncovering and questioning my own assumptions. How might libraries have been unintentionally complicit with systems that oppress? How might I be perpetuating these systems? Whether due to oversight or overt bias, when policies, collections, programming, etc. make access or service less welcoming or accessible for some patrons than others, that’s a problem that needs to be recognized and remedied.

+ +

Why do you identify with these ideas?

+ +

I grew up on the campuses of a couple different state schools for the Deaf/deaf, surrounded by people with different abilities and attributes than my own. If being part of this type of diversity taught me anything, it’s that another, more inclusive and just world is possible, but it will not happen on its own.

+ +

As an infrastructure that places profound potential for access in the hands of patrons and also respects their agency in determining what they want to pursue, libraries remain more open and accessible than our educational systems.

+ +

By identifying as a critical librarian, I hope to make this type of goal more visible & more common in libraryland, as well as just make it easier to find more like-minded people. As with other facets of identity, “critical librarian” is something I work with, through, and sometimes even against. I definitely believe that critical theory—particularly cultural studies—equips us with ways of investigating humans, human society, and producing social theory that can improve librarianship.

+ +

While I realize that some excellent librarians find the critical theory elements of critical librarianship off-putting, elitist, or otherwise exclusionary, I approach it as a set of useful tools for us to think through to improve what we do. More specifically, it’s a set of tools that work for me and my ways of thinking—I not only expect that your mileage will vary, but I’d love to learn more about what tools you’ve found most suitable.

+ +

Why do you participate in these chats?

+ +

As I’ve written elsewhere, I gravitate toward “why?” questions. I wanted a discussion group that addressed social issues in librarianship and hadn’t found one yet in my library school program. One thing I love about the chats is that it’s a unique opportunity to learn from a wide swath of people, some of whom are far more focused on “how?” questions.

+ +

I was quite close to deleting my Twitter account, but the #critlib chats & the people I’ve found through them kept me around! My understanding of library history, library pedagogy, and the many critiques of library practice would be completely impoverished if I didn’t have this network of people to learn from. More importantly, my toolbox of lenses to articulate, reflect upon, and improve my library practice would be far smaller—meaning that I’d be that much more likely to perpetuate systems of exclusion I don’t want to have existed in the first place.

+ +

Just as I hope to instill a life-long love of learning in my students and patrons, I hope to be a life-long learner. I’ve learned tons from these chats, and I look forward to learning much more.

+
+
    +
  1. +

    I don’t actually know whether Carnegie’s primary intention with open stacks was to minimize staffing requirements, with increased discoverability merely a felicitous by-product, or whether he viewed direct access as desirable itself. I’m still delving into these parts of library history, starting with Dee Garrison’s Apostles of Culture: The Public Librarian and American Society, 1876-1920. 

    +
  2. +
+
+ + + + +
+ + + + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/critlib-makerspaces.html b/critlib-makerspaces.html new file mode 100644 index 000000000..6924af42f --- /dev/null +++ b/critlib-makerspaces.html @@ -0,0 +1,677 @@ + + + + + + +#critlib Makerspaces — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + + + +

Friend or Foe?

+ +

Fry from Futurama wondering "Not sure if makerspaces are #critlib friend or neoliberal foe"

+ +

I recently had the pleasure of moderating a #critlib chat on Makerspaces. These spaces have been enjoying increasing popularity in libraries, demonstrating how libraries function as far more than warehouses for documents. At their best, makerspaces help community members learn by doing, regardless of whether these spaces operate in libraries or as institutions of their own. Participants can make critical interventions into their own lives using technology that would be prohibitively expensive, esoteric, or complicated to purchase and maintain for a single individual or household.

+ +

At the same time, makerspaces go beyond 3D printers or Raspberry Pi-based constructions. They bring along a host of explicit and implicit rhetorical, pedagogical, and cultural constructs—possibly bolstering neoliberal ideas about labor or education.1 With this potent brew of possibilities, it seemed a particularly worthwhile topic for a #critlib chat. In particular, I wanted to discuss the pedagogical possibilities in these spaces.

+ +

cat dressed like a chemistry professor saying "what's a #critlib opportunity in makerspaces? the petagogy"

+ +

#critlib?

+ +

If you’re unfamiliar with #critlib chats, they take the form of hour-long Twitter conversations on issues of critical librarianship. Using the hashtag “#critlib,” a moderator posts a series of questions and other participants respond. The conversations often get really lively, so it’s useful to use something like Tweetdeck to follow the hashtag in a dedicated column. Some chats are based on readings shared in advance and others revolve around recent events, participants’ experiences, or other knowledge.

+ +

As with most #critlib chats, this one was put into a Storify by another participant. This week’s keeper of the record was Sveta Stoytcheva, who goes by “oksveta” on Twitter and for her own website. She’s previously Storified other #critlib chats as well.

+ +

#critlib Chat Moderation

+ +

For anyone else interested in volunteering to moderate a #critlib chat, here’s a walk-through of the process. I initially proposed the following through the convenient online form on the #critlib Google Doc:

+ +
+

The “Makerspace” is an increasingly popular form that encourages lifelong learning, collective ownership of means of production, and active learning. At the same time, there are substantive concerns about such spaces’ ecological impact, their advocates’ propensity toward entrepreneurial boosterism, and their general tendency to promote “making” as producing individuated skills and physical outcomes rather than, for instance, fostering collective experiences or abstract insights.

+
+ +
+

What aspects of #critlib mesh well with Makerspaces (including, potentially, the active “making” pedagogy of digital humanities)? What aspects could benefit from substantive critique? What might a #critlib version of a Makerspace look like?

+
+ +

After getting confirmation from the moderators, I came up with a set of questions and looked for appropriate readings. Between proposing & moderating this chat, I participated in the moocmooc: Critical Pedagogies held by Hybrid Pedagogy journal. This provided a great reading for the connection I wanted to make between some opportunities shared by infoshops and makerspaces. I emailed the questions to the moderators for their feedback. After receiving it, I posted the questions a few days in advance so that anyone who wanted to could think about their contributions in advance—dealing with 140 characters is a skill, and time helps! I also made the two meme images here and used them to help spread the word about the upcoming chat on Twitter the couple days before.

+ +

Go ahead and check out the #critlib Google Doc to see when the next chat is taking place, or to propose a topic yourself! While you’re there, you can also see the links to a shared Zotero library of readings on critical librarianship and information about the past chats and any Storify transcripts that exist for them.

+
+
    +
  1. +

    Edit: Here’s a link to a great interview with Wendy Brown in which she discusses neoliberalism. It’s one of the better treatments I’ve seen of that term, which gets thrown around much more frequently than definitions of it do. Had this interview come out before the chat, I would certainly have asked people to read it. It would help distinguish between “making” in service of pedagogy (like the old Bauhaus or other constructivist pedagogical approaches) and a vision of libraries, passtimes, and recreation that must always be in service of easily marketable skills. 

    +
  2. +
+
+ + + + +
+ + + + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/critpotato-rhizo15-week-four.html b/critpotato-rhizo15-week-four.html new file mode 100644 index 000000000..6121aebf1 --- /dev/null +++ b/critpotato-rhizo15-week-four.html @@ -0,0 +1,696 @@ + + + + + + +Critical Hot Potato! aka #Rhizo15 Week Four — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + +

This post responds to the prompt for Week Four of #rhizo15: “How Do We Teach Rhizomatically?”.

+ +

For Week Four, Dave asked:

+ +
+

“I think there is value in the ‘course’ in the sense of the eventedness that it represents. It’s a chance for people to come together and focus on a particular topic… it’s one of the ways to garden the internet. But what is the role of the facilitator/teacher/professor where we are using learning subjectives, where learning isn’t measured and where content is actually other people? What cultural concepts do we have that we can use as models? Do we need a new model?

+ +

How do we ‘teach’ rhizomatically? Or, even… do we?”

+
+ +

This is a great question, particularly since it helps us think about the differences between “teaching” or “facilitating” and a more general “online learning community.” In order to help me think it through, I’ll examine the online community with which I’m most familiar, #critlib, which mostly happens online through Twitter & Tumblr, plus a few blogs.

+ +

#critlib operates more along a facilitation model than teaching model, for while there’s a small core of moderators who organize regular (weekly or biweekly) Twitter chats using the hashtag, the online conversation is most often an open, hour-long Q & A session around that session’s proposed topic. In my mind, at least, the hashtag abbreviates “critical librar*”; the * is sort of a Boolean wildcard, so it can be interpreted as librarian, librarians, librarianship, library workers, library activity, library institutions etc. equally. Critical librarianship, of course, predates the community that has connected through the hashtag on social media—thankfully! The tag’s ability to ambiguously refer to the moderated Twitter chats, the social media community that uses the tag during chats & otherwise, the pages on Tumblr and a Google Document moderated by the Twitter chats’ originators, and/or to critical librarianship has been an occasional nuisance, particularly during the Twitter chats when character limitations hinder disambiguation.

+ +

A “teaching” model—even its most open, Freirean variation that actively seeks to recognize the authority of the students and trouble the student/teacher distinction—seems to revolve around an established person or people who have some authority that persists from instance to instance. A “facilitation” model acts a little more “nomadically,” with facilitators only assuming the role of “central authority” on an ad-hoc basis, even if they do so successively over multiple sessions; put another way “facilitating” seems to refer more to the action currently being performed while “teaching” implies more of an identity and sense of authority. As Dave’s prompt implies, one of the great things about these models is that they help produce an “event,” either in the sense of a shift in perception—”okay, brain, gotta focus now!”—or in the more temporal sense of “Oh! I’ve gotta make it to Twitter between 9p-10p ET or I’ll miss #critlib!” As I’m writing this knowing that the prompt for Week Five concerns community learning, I’m going to leave that for my next post and focus here just on what teaching rhizomatically might mean.

+ +

Insert roughly two months of intermittently thinking about this, then deciding to come back to this after making a Storify of the #critlib chat in which we critiqued #critlib and revisiting Freire’s Pedagogy of the Oppressed a bit.

+ +

I’m not going to write a summary the “critiquing #critlib from within” session, since that seems against the motivation of the event. However, I do recommend you read through the Storify of it! Instead of a summary, I’m offering what it made me think in response.

+ +

The most striking thing to me about the recent chat was how different participants perceived barriers around the tag, seeing it more as an established community than group of people mediated by a tag. Perhaps online activities allow for more projection than in-person ones do, in that it’s not as easy to check our ideas with the people we’re physically capable of seeing/asking? Perhaps the rapid pace of an online chat it makes some people feel less comfortable asking for clarification? Perhaps it feels like going “on the record” for some people, rather than just chatting?

+ +

In any event, one of my favorite components was when people stopped being polite chatty and started being real.

+ + + + +

The other striking thing was how the participants ended up gauging shared experience/attributes. Much as we conversed by using a particular intermediary—the #critlib string—we also appealed to employment types of the moderators, to having read any Freire in order to see who had any pedagogical theory background, and to having read any Foucault. Since the online introductions are brief, there’s little chance to quickly learn the deeper background of the participants. I’m having a hard time imagining a twitter chat where people wrote up more detailed bios on other webpages and then linked to them instead of just using a couple tweets or the twitter bio, since that doesn’t really scale.

+ +

What we like to think of as “teaching” or “facilitating” often fundamentally remains closer to “shuttling thoughts around an incoherently, differently understood intermediary.” I’d apply this gloss equally to learning online and off, although the degree of play and range of different interpretation might be larger for online actions, since there are fewer constraints on understanding, attention, following up, etc. Indeed, if the goal of this post is coming up with another figure or model, as Dave invites us to do, I’m thrown back into thinking of queer theory’s insistence that terms operate as sites of resistance, struggle, and production of meaning.

+ +

Emily Drabinski has neatly outlined this aspect of queer theory in “Queering the Catalog”:

+ +
+

Where lesbian and gay studies takes gender and sexual identities as its object of study, queer theory is interested in how those identities come discursively and socially into being and the kind of work they do in the world. Lesbian and gay studies is concerned with what homosexuality is. Queer theory is concerned with what homosexuality does. (page 96) 1

+
+ +

Perhaps we can expand this into saying that it’s worth keeping in mind how even terms like #critlib function as shape-shifting hot potatoes as we shuttle them around, pliable boundary objects that continually morph as they move, taking on new facets that appear as distinct and obvious to one handler while remaining invisible, inaccurate, or even entirely fictitious to another—all of this play/change/deferred communication happening in a “community” built out of the people who touch the hot potato in whatever way makes meaning out of it for them.2 None of this happens exclusively within online learning communities, but perhaps they are more open to it.

+ +

If I’m going to offer a new model for online communities, I’ll do exactly what I’m describing, and mutate an extant term— #critpotato—into my (current) new figure of how online learning functions. We’ll see how long I sustain this model, or if it functions alongside another later.

+ +

More interestingly, does this slightly ridiculous & ludic figure of a critical, conceptual hot potato offer you anything useful? To tease out a link between Deleuze’s stance on what philosophy is for & Freire’s version of praxis: what actions might this conceptual tool support?

+ +
+
    +
  1. +

    Drabinski, Emily. “Queering the Catalog: Queer Theory and the Politics of Correction.” The Library Quarterly: Information, Community, Policy, Vol. 83, No. 2 (April 2013), pp. 94-111. Get it here! 

    +
  2. +
  3. +

    On top of being a lurid run-on, this sentence owes a lot to a couple images I dimly remember from past readings. One is of a soccer ball articulating—but not defining—the community who use it. I think this is an article on actor-network theory, but I spent an hour looking for it thinking it was by either Lawrence Lessig or Bruno Latour, and it seems to be neither. Any ideas for what it might actually be? edit 2015-07-05: It turns out the soccer ball image seems to originally come from Michel Serres’ chapter “The Theory of the Quasi-Object” in The Parasite. Quite fittingly, this image has later been kicked around by Brian Massumi, Patricia Clough, and others…including being mentioned on the last page of Latour’s “On actor-network theory. A few clarifications plus more than a few complications”…which I’m not sure I’ve actually read after all. Clearly I could use a better system for reading notes! :flushed: The other image comes from somewhere in Roland Barthes—I think?—where he compares words to onions, as neither has a proper “inside,” only layers upon layers of external skin. 

    +
  4. +
+
+ + + + +
+ + + + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/cv/index.html b/cv/index.html new file mode 100644 index 000000000..0d1fbd274 --- /dev/null +++ b/cv/index.html @@ -0,0 +1,919 @@ + + + + + + +CV — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

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

This page last updated 2023-11-19.
+Download an older version of this C.V. as a .pdf from 2015
+You may also see some of this on my portfolio page, last updated 2015-10-10.

+ +

Education

+ +

Idaho State University, Pocatello, ID
+currently enrolled, Ph.D. Program in English and the Teaching of English

+ +

Indiana University, Bloomington, IN
+Master of Library Science, (ALA Accredited) received July 2015

+ +
    +
  • Library courses focused on critical information literacy instruction, humanities subject librarianship, and digital humanities
  • +
+ +

University of Rochester, Rochester, NY
+Master of Arts in Visual and Cultural Studies, 2012

+ +
    +
  • Graduate studies focused on media, cultural studies, music, and democratic theory
  • +
  • Teaching assistant and instructor positions enhanced capacities to inspire undergraduates and graduate student peers with writing and critical thinking
  • +
+ +

University of California, Riverside, Riverside, CA
+Master of Arts in English, 2005

+ +
    +
  • Graduate studies focused on English and American literature, rhetoric, and literary theory
  • +
  • Teaching positions gave experience teaching freshman composition to one of the nation’s most diverse student populations
  • +
+ +

Bachelor of Arts in English, Cum Laude, with Minor in Film and Visual Culture, as well as Minor in Philosophy, 2000

+ +
    +
  • Undergraduate studies focused on American literature, film and media, and literary theory
  • +
+ +

Additional Education

+ +

School of Criticism and Theory Cornell University Ithaca, NY
+Certificate of Completion, 2009

+ +
    +
  • “Voice, Representation, Ideology” seminar with Dr. Michael Steinberg and Dr. Suzanne Stewart-Steinberg of Brown University
  • +
+ +

Instructional Designer and Librarian Experience

+ +

Idaho State University Pocatello and Meridian, ID

+ +

Instructional Designer
+Instructional Technology Resource Center, May 2022—present

+ +
    +
  • Support faculty with course design
  • +
  • Apply Quality Matters Rubric and related principles for course design
  • +
+ +

College of Western Idaho Nampa, ID

+ +

Instruction Coordinator and Faculty Outreach Librarian
+Library, October 2015–May 2022

+ +
    +
  • Coordinate library instruction program, including assessment of student learning and of library instruction sessions
  • +
  • Create instruction materials to support online and in-person library instruction and critical information literacy
  • +
  • Conduct outreach campaigns, programs, and events
  • +
  • Represent the library at faculty committee meetings
  • +
+ +

Indiana University Bloomington, IN

+ +

Maps Graduate Assistant / Map Collection Assistant / Government Information Reference Assistant
+Department of Government Information, Maps, and Microform Services, Herman B Wells Library, September 2013–July 2015

+ +
    +
  • Scanned maps at archival standards and managed Indiana Historical Maps Digital Collection +
  • +
  • Created digital displays, exhibits, finding aids, and instructional material
  • +
  • Maintained portions of the department website and blog
  • +
  • Provided reference service, handled circulation, and assisted patrons with multiple types of scanners and microform readers
  • +
  • Supervised other student workers
  • +
+ +

Assistant to the Subject Librarian for Germanic Studies, French & Italian, Philosophy, History & Philosophy of Science, Classical Studies, and Linguistics
+Department of Arts & Humanities, Herman B Wells Library, August 2014–July 2015

+ +
    +
  • Selected materials for French & Italian, Classical Studies collections according to collection development policies
  • +
+ +

Instruction Assistant
+Department of Teaching & Learning, Herman B Wells Library, September 2013–July 2015

+ +
    +
  • Designed and led instruction sessions for undergraduate courses in Business and Life Sciences
  • +
  • Consulted with professors to target session content to course outcomes and current assignments
  • +
  • Instructed researchers during individual drop-in sessions
  • +
+ +

Ethnographic Research Assistant
+Department of Library Academic Services, Herman B Wells Library, September 2013–July 2015

+ +
    +
  • Conducted field observations, transcribed recordings, analyzed and coded transcripts, and administered surveys for ethnographic studies of undergraduate and graduate library patrons
  • +
+ +

University of Rochester Rochester, NY

+ +

Rare Books Manuscripts Clerk
+Rare Books and Special Collections, Rush Rhees Library, May–August 2010

+ +
    +
  • Assisted librarians with accessioning and cataloging new materials
  • +
  • Registered patrons, pulled requested material, and maintained security of items in rare books reading room
  • +
+ +

Technical Assistant and Office Assistant
+Rush Rhees Library Digital Initiatives Unit, May 2007–November 2008

+ + + +

English, Visual and Cultural Studies, and ESOL Teaching and Tutorial Experience

+ +

Idaho State University Pocatello, ID
+Ph.D. Student Intern
+Department of English, January-April 2021

+ +
    +
  • Co-taught an online, asynchronous section of ENGL 3311: Literary Criticism and Theory
  • +
  • Co-taught and co-designed course with Dr. Matthew Levay, as one of two required internship/externship experiences in the Ph.D. Program in English and the Teaching of English
  • +
  • Shared in preparing weekly video introduction to course modules
  • +
  • Shared in designing and grading student assignments (weekly short responses, group “keyword” presentations, midterm and final exams, and paper)
  • +
+ +

Niagara County Community College Sanborn, NY
+Adjunct Instructor
+Department of English, August 2012–May 2013

+ +
    +
  • Instructor of record for three sections of English 101: Writing I in Fall 2012 semester, with up to 23 students per section
  • +
  • Instructor of record for one section of English 101: Writing I in Spring 2013 semester, with up to 23 students per section
  • +
  • Instructor of record for one section of English 102: Writing II and Introduction to Literature in Spring 2013 semester
  • +
  • Revised English 101: Writing I syllabus for Spring 2013 semester based on my assessment of student progress and outcomes
  • +
+ +

St. John Fisher College Rochester, NY
+Adjunct Instructor
+Department of American Studies, September–December 2012

+ +
    +
  • Instructor of record for “Film, Television, and Visual Culture,” a course on the history and interpretation of these media
  • +
  • Coordinated course content with two sections of English 101 as part of the college’s first-year Learning Community program
  • +
  • Incorporated technology into course by having students collaborate on final research projects they posted (in part) on Tumblr
  • +
+ +

University of Rochester Rochester, NY
+Writing Center Consultant
+Eastman Writing Center, Eastman School of Music, September 2010–May 2012

+ +
    +
  • Designed and lead workshops on such skills as developing thesis statements, citing and using sources, and crafting conclusions
  • +
  • Tutored undergraduate and graduate students in individual sessions
  • +
  • Assisted both ESL students and native speakers with academic and professional writing
  • +
+ +

Lecturer
+Department of Art History, January–May 2011

+ +
    +
  • Instructor of record for “Ways of Seeing: Audio-Visuality,” an Art History and Film/Media course on film soundtracks and sound art
  • +
  • Course required response papers, a final research paper, and an in-class oral presentation
  • +
+ +

Eastman Writing Seminar Instructor
+Department of Humanities, Eastman School of Music, September–December 2010

+ +
    +
  • Instructor of record for “Audio-Visuality,” a Freshman Writing Seminar using film and sound theory to develop critical thinking and writing skills
  • +
  • Course required response papers, a final research paper, and an in-class oral presentation
  • +
+ +

Teaching and Research Assistant, Graduate Program in Visual and Cultural Studies Department of Art History/Department of Comparative Literature, September 2006–May 2010

+ +
    +
  • As Teaching Assistant for “Writing on Art,” a required course for Art History or Studio Art Majors focusing on analytical skills and different styles of writing about art, aided professor with student writing assessment and provided students individual instruction
  • +
  • As Teaching Assistant for “Major Seminar,” a required course for majors in Comparative Literature and Foreign Language Majors that provides an overview of critical theory and applies these critical skills to the writing of literary essays, aided professor with student writing assessment and provided students individual instruction
  • +
+ +

University of California Riverside Riverside, CA
+Teaching Assistant
+Department of English, September 2004–June 2006

+ +
    +
  • Taught English 1A, 1B, and 1C of the Freshman Composition Series
  • +
  • Integrated literature, film, and music into class curricula to further engage students
  • +
  • Three distinct courses each required weekly compositions while focusing on progressively sophisticated scholastic writing
  • +
+ +

FLS International Glendora, CA
+ESL Instructor
+Summer 2005

+ +
    +
  • FLS is a program that offers courses and tutorial services for students for whom English is their second language
  • +
  • Planned and taught ESL class for international high school students using immersion techniques and creative writing exercises
  • +
+ +

Publications

+ +

Research Publications

+ + + +

OER Works

+ + + +

Instructional Design & Library Conference Presentations and Panels

+ +
    +
  • “Opening the Door to a More Inclusive and Equitable Learning Environment with UDL: Connecting UDL Guidelines and Quality Matters Specific Review Standards.” slides, handout.
    +Co-presented with Kimberly Tomkinson.
    +QM Connect 2023 +
  • +
  • “Student Scholars Creating OER through Renewable Assignments.” slides.
    +Invited talk, Co-presented with Liza Long.
    +Louisiana State University’s HEROE-S Forum, Conference held online, 2023.
  • +
  • “Student Scholars in Action: Collaborations with Librarians, Students, and Instructors for Student-Driven OER.” slides, links and related resources.
    +Co-presented with Liza Long and Carrie Bailey.
    +Open Education Conference 2022, Conference held online, 2022.
  • +
  • “Student Achievement Unlocked! The Effectiveness of Badging in Community College Library Instruction.” video, paper.
    +Co-presented with Amanda Nida and Kim Reed.
    +ACRL (Association of College & Research Libraries) 2021, Conference held online, 2020.
  • +
  • “Textbook Affordability & OER (Open Education Resources).”
    +Panel with Jonathan Lashley, Kristin Witman, Marco Seiferle-Valencia, and Monica Brown.
    +MOSS Meetup 2020, Conference held online, 2020.
  • +
  • “Will I Get Credit for my Badges?” slides.
    +Information Literacy Lightning Talk with Rebeca Peacock, Shelly Doty, and Lindsay Marsh.
    +MOSS Meetup 2020, Conference held online, 2020.
  • +
  • “SIFT Moves.” video
    +“Innovative Ideas” poster session / video lightning talk
    +MOSS Meetup 2020, Conference held online, 2020.
  • +
  • “Informing the Crisis of Fake News.”
    +Presentation.
    +Library Instruction West 2020, Conference cancelled due to COVID19 pandemic.
  • +
  • “Changing Tides: Exploring Current Trends in Information Literacy Programs.”
    +Panel with Zoe Fisher, Danielle Rowland, Megan Smithling, and Elizabeth Brown.
    +2017 ACRL Washington & Oregon Joint Conference, Eatonville, WA, 2017.
  • +
  • “ILA Social Justice Committee, Equity, and Libraries.” slides
    +Keynote presentation. +SWILA (Southwestern Idaho Library Association) Conference, Meridian, ID, 2017.
  • +
  • “Productive Interpretations: Encouraging Patron Agency through Cultural Criticism.” slides, paper.
    +CAPAL 2016 Conference, Calgary, AB, Canada, 2016.
  • +
  • “Critical Information Literacy as Collaborative Praxis.”
    +Co-presented with Jessica Critten, Karen Nicholson, and Eamon Tewell.
    +Cultural Studies Association Conference, Riverside, CA, 2015.
  • +
  • “LIS Education and New Conceptions of Democracy.” video and slides.
    +2015 Symposium on LIS Education, University of Illinois, Urbana-Champaign, 2015.
    +Presentation slides. +
  • +
  • “Undergraduate as Creator, Undergraduate as Curator: Exploring the Role of the Instruction Librarian in the Digital Humanities.”
    +Co-presented with Katherine Ahnberg, Megan Browndorf, and Cynthia Fisher.
    +The Collective, University of Tennessee, Knoxville, 2015.
    +http://sched.co/233V +
  • +
  • “Community Building Workshop.”
    +Co-led with Meghan McGrath.
    +Women in Information Science Symposium, Indiana University, Bloomington, 2014.
  • +
  • “Digital Maps at IU.”
    +Co-presented with Theresa Quill. Lighting Round talk.
    +IU Libraries In-House Institute, Indiana University, Bloomington, 2014.
  • +
  • “Don’t Know Much About [Digital] Humanities?” digital “ready reference” handout and slides.
    +Co-presented with Katherine Ahnberg.
    +New Directions in Information Fluency, Augustana College, Rock Island, Illinois, 2014.
  • +
+ +

Other Academic Conference Papers Presented

+ +
    +
  • “Is a Plant a Document? The Knowledge Practices of Renaissance Natural History, Francis Bacon, and Contemporary Library Science.”
    +Intermountain Graduate Conference, Pocatello, ID, 2019.
  • +
  • “Intersectionality and Juxtaposition in Mourning Dove’s Cogewea.”
    +Western Literature Association Conference, Estes Park, CO, 2019.
  • +
  • “’This is a musical instrument. This is another. Combine them. Now perform historical materialism through your band.’: Bricolage and Historical Materialism as Audible in the Altered Instruments of Sonic Youth and Laurie Anderson.”
    +Popular Culture Association/American Culture Association Conference, Boston, MA, 2012.
  • +
  • “Musical Mutations, Alternative Institutions: A Materialist Cultural Studies Approach to the Early Works of Laurie Anderson and Sonic Youth.”
    +Cultural Studies Association Conference, San Diego, CA, 2012.
  • +
  • “Marclay, Music, Materiality: Uncovering Discourses of the Body as Palimpsest and Presence.”
    +Making Sense of Visual Culture, University of Rochester, 2011.
  • +
  • “‘E Pluribus Unum’: Jacques Rancière, Sandy Bull, and the Peculiar Familiarity of Political Frustration in ‘New Weird America’ Folk Music.”
    +International Association for the Study of Popular Music-US Conference, Cincinnati, Ohio, 2011.
  • +
  • “Looking via Listening: Drexciya, the Acousmêtre, and Political Metaphors.”
    +PCA/ACA Conference, St. Louis, Missouri, 2010.
  • +
  • “(Freedom Forever) Elvis Lives!: Reanimation, Hauntology, and Symbolic Slavery.”
    +Visible Memories Conference, Syracuse University, 2008.
  • +
  • “Who? Me? Walking the Margins of Queer Visibility.”
    +(dis)junctions Conference, University of California, Riverside, 2006.
  • +
  • “David Wojnarowicz’s Use of Realist Representation in ‘Arthur Rimbaud in New York’.”
    +Theorising Queer Visualities: Postgraduate Symposium, University of Manchester (England), 2005.
  • +
  • “Her Majesty’s Secret Service: Containing the Corrupting Effects of Cultural Competency in Rudyard Kipling’s Kim.”
    +Contact, Contagion, and Containment Conference, Cornell University, 2005.
  • +
  • “‘Heliocentric Worlds’ and Creatures from a Black Platoon: Afrofuturist Redefinitions of the Nation in the Works of Sun Ra and Drexciya.”
    +(dis)junctions Conference, University of California, Riverside, 2004.
  • +
+ +

Memberships and Service

+ +

In the Library with the Lead Pipe journal.

+ +
    +
  • Editorial board member, Web editor, Publishing editor, Internal peer reviewer. 2015-present.
  • +
+ +

American Libraries Association

+ +
    +
  • Member, 2014-2019
  • +
+ +

ASIS&T Student Chapter, Indiana University, Bloomington

+ +
    +
  • Social Chair, 2014–2015
  • +
  • Member, 2014–2015
  • +
  • Co-organizer of Women in Information Science Symposium, 2014
  • +
+ +

Progressive Librarians Guild Student Chapter, Indiana University, Bloomington

+ +
    +
  • President, 2014-2015
  • +
  • Member, 2013-2015
  • +
  • Partnered with other local organizations on two main projects: Books & Beyond (to set up a school library in Rwanda) and Midwest Pages to Prisoners (to reply to book requests from prisoners with book selections and personalized letters)
  • +
+ +

Inter-Club Council, Department of Information and Library Science, Indiana University, Bloomington

+ +
    +
  • President, 2014–2015
  • +
  • Member, 2013–2015
  • +
  • Organized numerous workshops and presentations for the Peer Mentorship Program
  • +
  • Led initiative to have ILS student groups coordinate their events calendars using a shared Google Calendar
  • +
+ +

Indiana University Digital Humanities Working Group, Indiana University, Bloomington

+ +
    +
  • Founding member, 2014–2015
  • +
  • Led workshop on “Getting Started with Git and GitHub Pages,” 2014
  • +
+ +

Cultural Studies Association, National Association

+ +
    +
  • Member, 2011-12, 2014–2015
  • +
+ +

PCA/ACA (Popular Culture Association/American Culture Association), National Association

+ +
    +
  • Member, 2010–2012
  • +
+ +

(dis)junctions Conference, University of California, Riverside

+ +
    +
  • Panel Chair, 2006
  • +
+ +

Awards and Honors

+ +

University of Rochester

+ +
    +
  • Dean’s Teaching Fellowship Recipient for a graduate student teaching a course in Art & Art History department, 2010–2011
  • +
+ +

University of California, Riverside

+ +
    +
  • Dean’s Fellowship Recipient, 2003–2006
  • +
  • Michael Chesney Award for undergraduate English student working with music
  • +
+ +

Media and Communication Experience

+ +

Radio Disc Jockey

+ +
    +
  • WRUR 88.5 FM 2007–2012
  • +
  • KUCR 88.3 FM 2000–2006
  • +
+ +

Videotaping

+ +
    +
  • Numerous lectures and interviews at University of Rochester 2006–2011
  • +
+ +

Transcription of Anthropological Interview

+ +
    +
  • Interviews as part of the University of Rochester’s Digital Initiatives 2007–2008
  • +
+ +

Skills

+ +

Natural Languages: Reading proficiency in Spanish, French, and Latin. Basic speaking proficiency in Spanish and ASL.
+Web/Markup Languages: HTML5, CSS, XML, XHTML, TEI
+Web Content Management Systems: Pressbooks, WordPress, LibGuides, Jekyll, GitHub, Omeka
+Educational Content Management Systems: Moodle, Blackboard, Canvas
+Operating Systems: Mac OS X, Windows, UNIX
+Document Design: Adobe Creative Suite, Microsoft Office suite, Google Docs, Markdown & related tools, familiarity with LaTeX
+Citation Management Systems: Zotero, BibLaTeX
+Metadata Standards: Dublin Core
+Social Media: Twitter, Mastodon, Instagram, Facebook, Tumblr
+Audio Software: Ableton, Audacity, GarageBand, various plug-ins for each
+Others: Git (version control), Neatline (map and timeline suite for Omeka), MALLET (topic modeling)

+ + + + +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/del-hack-del-quirk-your-presentations.html b/del-hack-del-quirk-your-presentations.html new file mode 100644 index 000000000..ada018b0b --- /dev/null +++ b/del-hack-del-quirk-your-presentations.html @@ -0,0 +1,634 @@ + + + + + + +Hack Quirk Your Presentations — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + +

A new post of mine recently went up at Hack Library School. It’s about a simple technique that I’ve noticed can help instruction sessions or resource demonstrations feel a bit more exciting and memorable: highlighting a quirky result or aspect of the interface.

+ +

As a bonus, I talk about Batman, Wikipedia, and Google’s simple Ngrams viewer!

+ + + + +
+ + + + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/everything-counts-in-affective-amounts.html b/everything-counts-in-affective-amounts.html new file mode 100644 index 000000000..99aa5fae0 --- /dev/null +++ b/everything-counts-in-affective-amounts.html @@ -0,0 +1,685 @@ + + + + + + +Everything Counts in Affective Amounts — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + + + +

This post is for Week Two of #rhizo15.

+ +

Typing Hands Type What They Can

+ +

Over the last week I’ve effectively been teaching myself Zurb’s Foundation website framework as part of using it to make a prototype website for an information architecture course. Participating in #rhizo15 has primed me to really notice how the process mixes aspects of playful discovery with more structured “learning” outcomes.

+ +

If I were to measure this as a learning process, I could count:

+ +
    +
  • the new skills I’ve learned (even kludgey ones such as using the same naming convention in this prototype as for my regular website so that placeholder images appear when I’m testing it on my phone)
  • +
  • the hours I’ve spent on it
  • +
  • the features in whatever form the project becomes in the short-term and map them to intended “learning objectives”
  • +
  • the features in the final form and compare what I added & what I changed along the way
  • +
+ +

More interestingly, and to address this week’s question of “What can we count that isn’t learning?” I could count:

+ +
    +
  • the hours I’ve spent enjoying bits of the process
  • +
  • the hours I’ve spent frustrated or perplexed
  • +
  • how many items that produced these types of affective reactions
  • +
  • the times I’ve consulted the rather well-written documentation
  • +
  • the times I’ve committed something via Git (both to “save” it and so that I could try it out on my phone rather than using my laptop (more on Git below))
  • +
+ +

This list hews close to learning, but nevertheless feels as though it remains just adjacent to what we normally conceive of as “learning” when we focus on outcomes rather than processes. I wonder whether one might discuss zones of proximal affective engagement in addition to zones of proximal development? Enumerating the things in that zone would be a strange approach—but one that might let us dance just enough of that ‘ol defamiliarization/distantiation rag to truly consider affect and learning in new ways.

+ +

Affect isn’t quite countable, as it’s not discrete. It rapidly varies in intensity and mutates into inarticulable mutants of frustration, delight, and anticipation. This is something that we know as educators attentive to pedagogy, but it would be fascinating to find new ways to capture this process. Although this capture is not quite “counting,” it feels something other than the negative space around what is countable. Learning, affect, countable and non-count aspects all seem to flow through each other when we examine closely enough.

+ +

…An Extended Aside on Git and Open Humanities Notebooks

+ +

Git is version tracking software that allows users to annotate, compare differences, or roll back any changes that they save in text documents. It’s primarily used for software development, but as the Chronicle of Higher Education’s ProfHacker series on GitHub attests, Git and GitHub have a lot of potential for humanities and other forms of writing. For instance, if you were the curious type, you could see how many times I’ve edited this post after it went live. Typos are pesky and thoughts don’t stop arriving just because you’ve press a button.

+ +

Franny Gaede started an excellent Twitter discussion on “what a lab notebook for the humanities would look like”:

+ + + + +

…which led John Russell to share an illuminating post on open humanities notebooks, particularly history notebooks, by W. Caleb McDaniel.

+ + + + +

Although W. Caleb McDaniel doesn’t discuss Git’s potential in explicitly rhizomatic terms, his post makes clear many of the ways that Git helps document the messy process of assembling thoughts, evidence, discoveries, language, guiding questions, argumentative writing, and the other things that go into and get edited out of humanities writing.

+ +

I’m going on this extended aside on Git, GitHub, and open notebooks in part just to document what I’m learning at the moment and in part to tie this post back to my #rhizo15 post from last week, in which I mentioned that one of my learning subjectives for the course would be to share things a little before they’re ready. By directing people to Git, I’m highlighting the actual process of learning. I could then annotate it with all the subjective, affective, experiential, etc. aspects of the process adjacent to learning as I’d like and language allows.

+ + + + +
+ + + + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/favicon-16x16.png b/favicon-16x16.png new file mode 100644 index 000000000..3639f5a1e Binary files /dev/null and b/favicon-16x16.png differ diff --git a/favicon-32x32.png b/favicon-32x32.png new file mode 100644 index 000000000..405655f0b Binary files /dev/null and b/favicon-32x32.png differ diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 000000000..d23fc81e0 Binary files /dev/null and b/favicon.ico differ diff --git a/feed.xml b/feed.xml new file mode 100644 index 000000000..5e4aed908 --- /dev/null +++ b/feed.xml @@ -0,0 +1,144 @@ +Jekyll2023-11-27T01:37:22-07:00https://ryanpatrickrandall.com/feed.xmlRyan P. Randall"Ryan P. Randall's website"Ryan P. RandallObsidian Tasks patterns2023-11-18T19:52:10-07:002023-11-18T19:52:10-07:00https://ryanpatrickrandall.com/notes/obsidian-tasks-patterns<p>As I’ve mentioned a few times, I began using Obsidian earlier this year. Ultimately, the Tasks plugin was what convinced me to adopt it, despite my fondness for Dendron and my general hesitations/frustrations about Obsidian.</p> + +<p>It took quite a bit of delving into the Obsidian Discord forums and subsequent experimentation to figure out some of the queries and filters that best suit my brain.</p> + +<p>If you’re considering using a Markdown-related tool for tracking tasks, you might take a look at my note on the <a href="/notes/Note-taking/Obsidian/obsidian-tasks-plugin-patterns">Obsidian Tasks plugin patterns</a> I’ve found most useful.</p>Ryan P. RandallHow I use the Tasks plugin for Obsidian.AcWriMo20232023-10-31T17:47:58-06:002023-10-31T17:47:58-06:00https://ryanpatrickrandall.com/acwrimo2023<p>As I recently mentioned on Mastodon, I’m going to try doing Academic Writing Month (aka “AcWriMo”; a fellow traveler of National Novel Writing Month, or “NaNoWriMo”) this year. Here I’m detailing my approach—I’ll likely also update this with my progress throughout the experiment.</p> + +<h2 id="la-lucha-continúa">La Lucha Continúa</h2> + +<p>My most consistent writing challenge has always been that writing anything longer than a blog post involves a noticeable state shift. I move—sometimes with effort, sometimes all-too-effortlessly—from mild-mannered riotnrrrd mode to superhuman hyperfocus mode, and occasionally veer into full-on ADHD lasereyes goblin mode.</p> + +<p>This routinely produces good class &amp; conference papers, but isn’t exactly compatible with what one might call responsible adulting.</p> + +<p>So the crux of my dilemma: how to flip my brain into writing mode in sustainable ways that are in fact compatible with responsible adulting?</p> + +<h2 id="acwrimo2023-piece">AcWriMo2023 Piece</h2> + +<p>Here are this year’s AcWriMo experiment parameters, written up somewhat as <a href="https://www.moma.org/magazine/articles/407">a Fluxus piece</a>:</p> + +<ol> + <li>Aspire to get into the “writing headspace” for 30 minutes to an hour every other day, i.e. Mon or Tue, Wed or Thu, Fri or Sat., through November 2023.</li> + <li>Track the attempts. Probably share the progress &amp; results.</li> + <li>“Writing headspace” here ≅ “successfully opened up my writing app and/or successfully annotated readings in one of my two reading apps.”</li> +</ol> + +<p>As you can see, this is taking a process-based approach, not a product-based one. The aim is to see how much I can make a habit of writing in rally mode (i.e. sustained movement) rather than sprinting mode.</p> + +<p>To provide more structure and internal support, I’ve made myself a set of tasks, using Obsidian’s Tasks plugin. Whatever stands a good chance of supporting beneficial progress, right?</p> + +<h2 id="obsidian--tasks-details">Obsidian &amp; Tasks Details</h2> + +<p>While I haven’t yet written a post or note about the Tasks plugin specifically, it’s essentially what has drawn me from Dendron to Obsidian. So here I’ll detail how I’m using Tasks to help out with AcWriMo2023, in case you’re the sort of person who appreciates worked examples. If you’re also an Obsidian user, maybe it’ll be a useful example of how you might approach projects &amp; to-dos, using the Tasks plugin?</p> + +<p>Here’s a link to the <a href="https://github.com/ryan-p-randall/some-obsidian-starter-files/blob/main/files/writing-acwrimo-2023.md">project tracking file</a> I’ve made for this month’s challenge. Please adapt it to your own use as you’d like! (Here’s a link direct to the file’s <a href="https://raw.githubusercontent.com/ryan-p-randall/some-obsidian-starter-files/main/files/writing-acwrimo-2023.md">raw view</a>, if you just want to copy &amp; paste it from your browser without seeing all the GitHub interface.)</p> + +<p>A few important use/configuration notes:</p> +<ul> + <li>I use <code class="language-plaintext highlighter-rouge">#tt</code> as a global filter for Tasks. This tells the plugin not to track every single line that starts with a <code class="language-plaintext highlighter-rouge">- [ ]</code> checkbox, but only pay attention to the ones that start with <code class="language-plaintext highlighter-rouge">- [ ] #tt</code>. I’ll explain my reasons further in that eventual note, but for now, you’ll likely want to find &amp; delete all of those tags, or find &amp; replace them all with your own global filter if you use one.</li> + <li>I have <code class="language-plaintext highlighter-rouge">#td/writing</code> as an additional tag on each of these tasks. Using this sort of tag lets me use <code class="language-plaintext highlighter-rouge">#td</code> as a tag for all my “todo” tasks, then use the <code class="language-plaintext highlighter-rouge">/whatever</code> content to create subsets to display anywhere I want to have a Tasks query. Again, I’ll eventually explain this further; for now, I’m just giving any potential users of this a heads up.</li> + <li>I’ve also included the due dates for my own purposes. Again, you’ll want to change those for your own scenario. I’m just sharing all this, both to document it for Future Me and to help provide potential structures for anyone else who wants to give AcWriMo a go, last-minute.</li> + <li>There’s a Tasks query included in the file, under the <code class="language-plaintext highlighter-rouge">Tasks View</code> heading. This will display all the tasks on this very file, putting them in a dynamic pane that lets you change dates and interact with things more handily than you can with the Markdown / text view alone.</li> + <li>I feel like way too many people approach Obsidian as though there’s a single “correct way” to use it for tasks or projects. If you’ve read this far—and especially if you’re actually considering using my file—please approach it just as a springboard for your own experimentation. What I think might work for me, right now, isn’t guaranteed to work for me—let alone for you! I’d love it if you let me know that you found it handy or inspiring, of course.</li> +</ul> + +<p>Good luck finding what might work for you!</p>Ryan P. RandallHere's how I'm giving Academic Writing Month a go this year.My Obsidian plugins shortlist2023-10-23T11:08:34-06:002023-10-23T11:08:34-06:00https://ryanpatrickrandall.com/notes/obsidian-plugins<p>Over the weekend, I wrote a note with a short list of the <a href="/notes/Note-taking/Obsidian/obsidian-plugins">Obsidian plugins</a> that do the most to make it feel like “my” notes.</p> + +<p>I’m already planning to detail some of these further in separate notes. If that’s somehow your sort of preferred reading, stay tuned!</p>Ryan P. RandallThe plugins I use most with Obsidian.I’ve Been Using Obsidian2023-10-12T21:32:31-06:002023-10-12T21:32:31-06:00https://ryanpatrickrandall.com/notes/beginning-to-use-obsidian<p>I’ve been using Obsidian, the app for linked notes.</p> + +<p>I’ve written a note with <a href="/notes/Note-taking/Obsidian/beginning-to-use-obsidian">some first thoughts</a>, and I’m planning to write more already.</p>Ryan P. RandallI've been using Obsidian. Both enthusiastically and reluctantly.Light Mode in Progress2023-06-11T21:59:37-06:002023-10-12T21:44:14-06:00https://ryanpatrickrandall.com/light-mode-in-progress<p>Today—the day after I finished up a “16 weeks condensed into 4” Spanish class—I happened to read some folks on Mastodon talking about <a href="https://social.pixie.town/@joepie91/110526984317454201">light themes</a> on websites.</p> + +<p>I’ve been wanting to add one to my site for years, my brain apparently wanted a project I could reasonably <del>accomplish</del> make noticeable progress toward within a day, <strong>and</strong> I vaguely remembered having seen other <a href="https://github.com/mmistakes/minimal-mistakes/discussions/2033#discussioncomment-257421">Minimal Mistakes theme users discussing how to implement this</a>.</p> + +<p>Thus far today I’ve managed to have my Jekyll-based site correctly generate two different themes: the dark one I’ve been using for years and another light one that’s basically the default theme with a couple of colors switched out. That’s a success!</p> + +<p>Currently this site defaults to my regular dark theme, but will serve a light theme if it sense that you have “prefers light mode” set in your browser or operating system.</p> + +<p>Today’s work also lays the foundation for adding a toggle. That’s successfully building toward a future success!</p> + +<p>There are going to be some surprises along the way to a fully-featured light mode, such as noticing <strong>and also fixing</strong> the fact that the Bigfoot pop-up colors aren’t really legible at the moment. I’ll need to figure out how many of these things I can avoid hard-coding in the future. But it’s nice to finally work on it, even if doing so was somewhat of a surprise today.</p> + +<h2 id="update">Update</h2> + +<p>As of 2023-10-12, I’ve mostly fixed the things I had noticed with the theme. (They were inaccessible text and background colors related to footnotes and notices.)</p> + +<p>My next ambitious stretch goal will be to make a few <a href="https://fossheim.io/writing/posts/accessible-theme-picker-html-css-js/">user-selectable themes</a>, like Sarah L. Fossheim has done on their site. I’m also considering a move from <a href="https://web.archive.org/web/20221127194150/http://www.bigfootjs.com/">Bigfoot</a> to <a href="https://littlefoot.js.org/">Littlefoot</a> for the fancy pop-up footnotes.</p>Ryan P. RandallToday's work on putting together a light mode.Weekly Assemblage for 2023 Week 172023-04-30T13:49:46-06:002023-04-30T13:49:46-06:00https://ryanpatrickrandall.com/weekly-assemblage/wa-2023-week-17<p class="notice"><a href="/weekly-assemblage/weekly-whaaa">Weekly Whaaa…?</a></p> + +<p>Wow! This month has kept me busy—so much that I haven’t been updating this weekly.</p> + +<h2 id="vs-code-snippets-and-spellcheck-customizations">VS Code Snippets and Spellcheck Customizations</h2> + +<p>At the beginning of the month, I made a couple of new notes.</p> + +<p>One explains some <a href="/notes/Technology/VS-Code/vs-code-snippets">snippets</a> I often use, both in VS Code and other places. Right now, as I started writing this, I also made a new one for the Jekyll frontmatter for these Weekly Assemblage notes. Hopefully being able to create 17 lines of code just by typing out <code class="language-plaintext highlighter-rouge">;wa</code> will help me write these more regularly! (Or maybe I’ll switch to doing monthly updates?)</p> + +<p>The other new note covers <a href="/notes/Technology/VS-Code/vs-code-spellcheck-squiggles">spellcheck squiggles in VS Code</a>, and how make to them just perceptible enough.</p> + +<h2 id="designing-for-motivation">Designing for Motivation</h2> + +<p>As I’ve been (perpetually) trying to refine my text-based system for keeping track of tasks and projects, I’m realizing yet again that one missing component is rewarding myself and designing patterns that increase motivation.</p> + +<p>I’m going to revisit <a href="https://davidseah.com/productivity-tools/">Sri Seah’s Productivity Tools</a> and see what elements I might glean from them, as well as figure out what’s the minimum viable use of pomodoros that will help me feel like I’m moving forward when the work I’m involved with can take weeks or months.</p>Ryan P. RandallVS Code Snippets and Spellcheck customizations. Designing for motivation.New note on Spellcheck Squiggles in VS Code2023-04-01T19:04:19-06:002023-04-30T13:56:14-06:00https://ryanpatrickrandall.com/notes/new-note-on-spellcheck-squiggles-in-vs-code<p>I made a new note about <a href="/notes/Technology/VS-Code/vs-code-spellcheck-squiggles">spellcheck squiggles in VS Code</a>, and how to make them just perceptible enough.</p>Ryan P. RandallIf you find the default indicators distracting, here's how to customize them.New note on Snippets and VS Code2023-04-01T19:04:04-06:002023-04-01T19:04:04-06:00https://ryanpatrickrandall.com/notes/new-note-on-snippets-and-vs-code<p>Last week I made a new note about some <a href="/notes/Technology/VS-Code/vs-code-snippets">snippets</a> I often use, both in VS Code and other places.</p> + +<p>I’m continuing to update the note with additional snippets. In fact, I just added three about time and dates.</p>Ryan P. RandallType similar things often? Here are some snippets you can use in VS Code.Weekly Assemblage for 2023 Week 122023-03-26T00:00:00-06:002023-03-26T00:00:00-06:00https://ryanpatrickrandall.com/weekly-assemblage/wa-2023-week-12<p class="notice"><a href="/weekly-assemblage/weekly-whaaa">Weekly Whaaa…?</a></p> + +<h2 id="patterns-for-vs-code">Patterns for VS Code</h2> + +<p>The last couple of weeks I’ve been helping some faculty members create more accessible data tables. That kind of repetitive structure is a great candidate for a code snippet—so I made a few!</p> + +<p>Here’s the surprisingly long <a href="/notes/Technology/VS-Code/vs-code-snippets">VS Code Snippets note</a> I just wrote explaining how I use snippets, and annotating a few examples I think others might find useful.</p> + +<h2 id="auroras-unseen">Auroras Unseen</h2> + +<p>There were notable aurora in the sky one night this week, but our local conditions were drizzly or overcast, with a side helping of snow flurries.</p> + +<p>However, we’ve got a new plan in place for the next time the conditions are favorable! Last time we tried to see them, we drove out to <a href="https://parksandrecreation.idaho.gov/parks/bruneau-dunes/">Bruneau Dunes State Park</a>, which is lovely for seeing the night sky. However, for aurora, we’d probably want to head north of Boise, so now we’ve got an updated destination in mind that won’t take nearly as much driving time.</p> + +<h2 id="executive-function-as-a-public-good">Executive Function as a Public Good</h2> + +<p>As I wrote on <a href="https://hcommons.social/@ryanrandall/110087018243882320">Mastodon</a>, I recently found out that our local <a href="https://www.ridgetorivers.org/trails/interactive-map/">Ridge to Rivers</a> trail system has started posting QR codes that link to an interactive trail map.</p> + +<iframe src="https://hcommons.social/@ryanrandall/110087018243882320/embed" class="mastodon-embed" style="max-width: 100%; border: 0" width="400" allowfullscreen="allowfullscreen"></iframe> +<script src="https://hcommons.social/embed.js" async="async"></script> + +<p>I’d found myself out exploring and absentmindedly had the impulse “let’s go <strong>up</strong>,” even though if I’d taken a second to consider, I’d have realized that our drizzle and snow flurries had been perfect weather for muddy trails.</p> + +<p>So I appreciated how bluntly this sign reminded me to check the trail conditions, before accidentally contributing to the gouges, ruts, and other damage the trails have suffered in recent years. I certainly don’t want to have those guilty feet I’ve heard described in song!</p>Ryan P. RandallPatterns for VS Code.Weekly Assemblage for 2023 Week 102023-03-10T17:04:41-07:002023-03-10T17:04:41-07:00https://ryanpatrickrandall.com/weekly-assemblage/wa-2023-week-10<p class="notice"><a href="/weekly-assemblage/weekly-whaaa">Weekly Whaaa…?</a></p> + +<h2 id="week-of-sidequests">Week of Sidequests</h2> + +<p>In many ways, this week has felt like a bundle of sidequests, with little obvious at the end. But hey, some weeks are like that. I ended up spending a lot of time doing spring cleaning of my task notes.</p> + +<h2 id="foss-and-crafts-podcasts">FOSS and Crafts Podcasts</h2> + +<p>For the first time in weeks—possibly months?—I found the urge to listen to podcasts. I used to listen to lots of podcasts while commuting, but now I mostly do so only while doing chores or riding my stationary bike. I skimmed through the episodes I’d noted as ones I wanted to hear, and quickly chose to listen to an episode of <a href="https://fossandcrafts.org/about/">FOSS and Crafts</a>… and I’m very glad I did!</p> + +<p><a href="https://fossandcrafts.org/episodes/24-get-organized.html">Episode 23: “Get Organized!”</a> really spoke to me in terms of recounting the many ways that neurotypical planning practices utterly fail ADHD minds. I also appreciate the reminder about using a HipsterPDA<sup id="fnref:hpda" role="doc-noteref"><a href="#fn:hpda" class="footnote" rel="footnote">1</a></sup>, as well as the enthusiasm about <a href="https://orgmode.org/">Org-mode in Emacs</a>.</p> + +<p>This led to me listening to <a href="https://fossandcrafts.org/episodes/41-learning-emacs.html">Episode 41: “Learning Emacs”</a> just a day or two later. I’m very happy using VS Code, as <a href="/notes/Technology/VS-Code/index">my VS Code notes</a> should make clear. However, I’ve often hear Org-mode spoken of as the ultimate final form of outlining and task management in plain text files—a sentiment decidedly reinforced by this episode!</p> + +<p>So I ended up spending a few hours on Saturday afternoon thinking through the irritations I find with my current note setup—the main one being that I don’t have the fully automagical agenda I’ve heard Org-mode can offer. But after doing more digging, and considering how much yak shaving might go into fully switching from Dendron, I’m instead just going to try to lean harder into practicing the task management strategies I have, and see if they’ll suffice when done more consistently.</p> + +<h2 id="a-question-of-tasks">A Question of Tasks</h2> + +<p>I’m not going to take the time right now to fully write up my current task-wrangling practices in another note. But in brief, I’m using <a href="https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.todo-tree">Todo Tree</a> and <a href="https://wiki.dendron.so/notes/SEASewZSteDK7ry1AshNG/">Dendron’s Task Notes</a> with a particular hierarchy.</p> + +<p>The main “innovation” here is that I’ve made placeholder task-viewing notes with wildcards in the paths. When I use Dendron’s preview on one of these, I can see all notes whose path matches specific patterns. I’m using <code class="language-plaintext highlighter-rouge">tp</code> as a hierarchy for any open tasks in a project, and <code class="language-plaintext highlighter-rouge">ta</code> for task archive in a project.</p> + +<p>Provided I’m following those patterns in making notes, this means I can have a note whose body text consists entirely of <code class="language-plaintext highlighter-rouge">![[diss.**.tp.**]]</code>. Then, when I use Dendron’s preview on this, I’ll see links to any notes in my dissertation (“<code class="language-plaintext highlighter-rouge">diss</code>”) set of notes that have a parent note named <code class="language-plaintext highlighter-rouge">tp</code>.</p> + +<p>I can do the same for other hierarchies of notes, too: a <code class="language-plaintext highlighter-rouge">![[work.**.tp.**]]</code> and <code class="language-plaintext highlighter-rouge">![[home.**.tp.**]]</code> file would let me see matching notes for those domains.</p> + +<p>So I’m currently using that set up to track and differentiate tasks, to keep from being overwhelmed. The main question still is how to tag things for urgency and findability, without being dispirited by how many things I also could be doing. This trap of overwhelming Future Me is what has driven me away from my past approaches, like OmniFocus, Tasks, Taskpaper, etc.</p> + +<p>Here’s hoping that by using Todo Tree’s tags for just my most important and rewarding tasks, then tracking the rest with those wildcard-viewing notes, I’ll get the balance right.<sup id="fnref:dp" role="doc-noteref"><a href="#fn:dp" class="footnote" rel="footnote">2</a></sup> I’ll be sure to write more extensive notes on the process, if this experiment pans out well.</p> + +<div class="footnotes" role="doc-endnotes"> + <ol> + <li id="fn:hpda" role="doc-endnote"> + <p>It’s just a bunch of notecards held together with a binderclip. That’s it, that’s the thing. <a href="#fnref:hpda" class="reversefootnote" role="doc-backlink">&#8617;</a></p> + </li> + <li id="fn:dp" role="doc-endnote"> + <p>I guess I could have woven only a single Depeche Mode allusion in here, but I just can’t get enough. <a href="#fnref:dp" class="reversefootnote" role="doc-backlink">&#8617;</a></p> + </li> + </ol> +</div>Ryan P. RandallA week of sidequests. FOSS and Crafts podcasts. Notes spring cleaning. \ No newline at end of file diff --git a/freire-and-critical-librarianship.html b/freire-and-critical-librarianship.html new file mode 100644 index 000000000..232719524 --- /dev/null +++ b/freire-and-critical-librarianship.html @@ -0,0 +1,674 @@ + + + + + + +Freire and Critical Librarianship — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + +

This post is for Week One of MOOC MOOC: Critical Pedagogy.

+ +

Cover image of Pedagogy of the Oppressed

+ +

Processes. Processes, all the way down.

+ +

That’s what strikes me most about the first three chapters of Freire’s The Pedagogy of the Oppressed: his insistence on processes of becoming, of history, of liberation, and of course, of pedagogy through dialogue.1 This insistence on processes profoundly helps make sense of Chapter Two, the chapter most commonly referenced among educators intent on discussing critical pedagogy. The other main thing that sticks out is Freire’s particular brand of humanism—a humanism made palatable to someone fond of Foucault’s deep questioning of anything like an inherent “human nature” precisely by Freire’s attention to historical and interpersonal processes of becoming.2

+ +

Freire’s humanism-of-becoming also works due to his use of words like “love” and “generosity,” which focus on actions toward others rather than supposedly interior attributes or essences that have been repeatedly been shown to be historically and socially produced. Two great reads about this social & historical specificity are Shawn Michelle Smith’s American Archives: Gender, Race, and Class in Visual Culture and Allan Sekula’s “The Body and the Archive.” I mention these in particular as they focus on the role of archives in helping to produce these social effects, something to be kept in mind by fellow critical library & information studies people.

+ +

Freire’s problem-posing method aims to develop agency within those who are oppressed—those who see their position as timeless, static, and therefore impossible to change. The details in Chapter Three make it abundantly clear that he’s discussing adult education rather than the K-12 and higher education settings to which his thought is often directed in America. While this shift certainly doesn’t mean that his discussion of the “banking model” or his preference for problem-posing and dialogue are misguided, it’s still worth paying close attention to the specifics of current education to anticipate the snags that might arise if one tried to unthinkingly wrench his problem-posing method out of his particular historical situation. One could certainly argue that someone who thinks that education is ultimately justified to the degree it accomodates a student to the workplace has been oppressed by neoliberal ideology. Even for those hesitant to take this tack, Freire’s problem-posing, dialogic method makes a great case for preparing students to become agents capable of critical thinking and thoughtful engagement with the world.

+ +

What I’m left wondering about with importing Freire’s method to American education, particularly higher education, is ultimately less about the problem-posing, dialogic method itself and more about what sorts of structural changes might be necessary to help educators pursue it. To wit, here’s a partial list of conundrums:

+ +
    +
  • the increasing “feminization” of educators, particularly librarians, teaching assistants, and/or adjuncts
  • +
  • the tendency of educators to think of how Freire can apply to “their own” classrooms rather than to departments, campuses, or wider educational systems
  • +
  • the tendency for some educators & students to look at librarians primarily in their “service” rather than instructional capacities
  • +
  • the pervasive gender bias that many women, particularly those of color, experience in STEM professions and in educational settings
  • +
+ +

In differing ways, each of these concerns decreases the ability of educators to function as “guides on the side,” a useful metaphor and interface from the University of Arizona Libraries whose use of active learning was amplified by Meredith Farkas.

+ +

Ultimately, my question is less about how we should foster Freire’s problem-posing pedagogy within individual classrooms and more about how we can reshape education to enable it throughout our campuses and society. To me, critical librarianship is one approach, as it helps students become capable lifelong learners. Although librarians like Emily Drabinski and Barbara Fister have advocated critical approaches to librarianship for years, posts such as Brian Mathews’ recent column for the Chronicle of Higher Education show that “#critlib” is receiving attention in venues beyond libraryland.

+ +

Revisiting Freire also has helped me work toward a more succinct personal vision of critical librarianship, one attentive to critical theory while always placing it in the service of “the continuing transformation of reality” (92). As Freire writes, “Problem-posing education affirms men and women in the process of becoming—as unfinished, uncompleted being in and with a likewise unfinished reality. […] The unfinished character of human beings and the transformational character of reality necessitate that education be an ongoing activity” (84).

+ +

Here’s hoping that more educators look to being “guides on the side” who help learners of all ages confront systems of information, knowledge, and education that might not be designed with generosity—and that critical librarianship helps us learn to design information systems with such generosity in mind.

+ +
+
    +
  1. +

    All page numbers refer to the 30th Anniversary Edition, whose pagination seems to differ from those used elsewhere in this MOOC MOOC. 

    +
  2. +
  3. +

    While I have a few small quarrels with Freire when he writes about things like “the individual’s ontological and historical vocation to be more fully human” (55) as if they are true in an ahistorical sense, overall it’s hard not to appreciate a pedagogy aimed at confronting “a culture of domination” (54). Since I’ve been reading Gilles Deleuze as critiqued by Rosi Braidotti, I’ll just call this a humanism-of-becoming in hope that this will allow for an expansive humanism that allows for affectivity, intersectional identities, and non-unitary subjects. 

    +
  4. +
+
+ + + + +
+ + + + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/git-lfs-3.1.4-r5.apk b/git-lfs-3.1.4-r5.apk new file mode 100644 index 000000000..c509499c2 Binary files /dev/null and b/git-lfs-3.1.4-r5.apk differ diff --git a/how-do-you-take-notes-or-markdown-and-bullet-journals.html b/how-do-you-take-notes-or-markdown-and-bullet-journals.html new file mode 100644 index 000000000..31f3e31a1 --- /dev/null +++ b/how-do-you-take-notes-or-markdown-and-bullet-journals.html @@ -0,0 +1,636 @@ + + + + + + +How Do You Take Notes (or Markdown and Bullet Journals) — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + +

Here’s a post I wrote for Hack Library School discussing Markdown and the Bullet Journal system for note-taking. Markdown is a simplified way of writing html, and happens to also be what I use when writing this site through Jekyll and GitHub Pages. Bullet Journals are a system not for classroom or lecture note-taking, but rather for everyday notes about actions, ideas, or projects.

+ +

An aside on Markdown not in that Hack Library School article: Sometime I plan to write a few posts on this blog about how I made this site with Jekyll and GitHub Pages, both of which use Markdown. I actually write all the notes that I type in Markdown format (or a variant) because I prefer plain text files and being able to output from there to all sorts of different presentation formats like .docx, .pdf, or .rtf. Oddly enough, I starting using it because earlier versions of iOS didn’t have a way of writing notes that allowed for formatted text, so Markdown started taking off among people who had iPhones but wanted to write links (or italics for academic citations). I’m glad I started using Markdown, even if I do so because of technical limitations, because I think it’s a highly useful way not just for writing for the web but also for taking notes and writing in the most lightweight, future-proof format possible.

+ + + + +
+ + + + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/index.html b/index.html new file mode 100644 index 000000000..aa1ad0e9a --- /dev/null +++ b/index.html @@ -0,0 +1,721 @@ + + + + + + +Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+ + + + +
+ + +
+ + + + +

About Me

+ +

As an Instructional Designer at Idaho State University, I work to help faculty design engaging, clear, and accessible online courses that improve outcomes for every learner. I'm enthusiastic about open educational resources (OERs) and open pedagogical approaches.

+ +

I'm also a student in Idaho State University's Ph.D. in English and the Teaching of English program, which emphasizes pedagogy more than most English literature programs. I serve as the Web Editor for In the Library with the Lead Pipe, an open access, open peer reviewed library journal.

+ +

In my previous role as the Instruction Coordinator and Faculty Outreach Librarian for the College of Western Idaho, I worked with students, other librarians, faculty, and staff to promote critical information literacy and library use.

+ +

Prior to librarianship, I earned an MA in English from the University of California, Riverside and an MA in Visual and Cultural Studies from the University of Rochester. While a graduate student, then as an adjunct, I taught what librarians call information literacy skills as the instructor for many first-year writing seminar courses and lower-division American Studies and Film/Media courses. I was also a college writing tutor for undergraduate and graduate students. The path of librarianship took me to IU Bloomington's MLS program, where my favorite courses emphasized critical information literacy, humanities subject librarianship, and digital humanities.

+ +

Outside of that more clearly academic stuff, I've hosted a college radio show on KUCR & WRUR, been in a band or two, and learned from participation and collective study in various do-it-ourselves communities. If you're looking for communities related to librarianship, you might start by checking out #critlib, The Librarian Parlor, and Hack Library School, each of which I often look to for insights.

+ +

CV

+ +

If all of this somehow leaves your curiosity unsated, here's my CV.

+ +

Other Pages

+ + +

Featured Posts

+ +
+ +

critlib #feelings

+

Why do I #critlib? Because another librarianship is possible.

+ + +
+ +
+ +

Freire and Critical Librarianship

+

For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship.

+ + +
+ + +

Recent posts

+ + + + + +
+ +

AcWriMo2023

+

Here’s how I’m giving Academic Writing Month a go this year.

+ + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/learning-subjectives.html b/learning-subjectives.html new file mode 100644 index 000000000..383c3979f --- /dev/null +++ b/learning-subjectives.html @@ -0,0 +1,654 @@ + + + + + + +Learning Subjectives — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + +

This post is for Week One of #rhizo15.

+ +

Here’s something I constantly rediscover, sometimes painfully: although I’m a capable writer, I’m predisposed toward research. This orientation seems both a boon and a hindrance as an aspiring academic librarian.

+ +

Research calls to me in large part because of its rhizomatic nature—I jump into searching & reading, then giddily test out new possibilities along the way. It feels a lot like being in an exuberant dancefloor, with connections of myriad types & durations constantly occurring and altering. At the other extreme, too often when I am “writing,” I want things to already be perfected and stable. I prioritize the product rather than embracing the process.

+ +

If I were to make a goal—some sort of objective for myself from participating in #rhizo15—I’d have it be something about getting used to writing in ways that are more like this rhizomatic unfurling and becoming rather than the more linear, hierarchical, arborial notion that academic disciplines expect us to produce all too often.1

+ +

Phrasing this another way, in terms of actions rather than affect, I’m going to try to post things perhaps a little before I feel they are “ready,” to share stages in a process rather than try to produce stable documents intended for longer durations. At least here, at the beginning of #rhizo15, I’m going to try to post midway-pieces, thoughts that dwell long enough for linguistic articulation, but not necessarily long enough to have any presumptions beyond being points in an as-yet-unstable trajectory. Rather than a draft, this is just a sketch, one ball of a pinball game, or one turn in a skateboarding videogame; with so little at stake, I’ll likely remain more open to discovering & learning. Speaking of games, the possibilities of alternate, explorative models are part of what excites me about digital humanities tools and how they might allow for demonstrating humanities thought processes more readily than essays do.

+ +

Interestingly, I had a delightful and productive research interview while these thoughts circled in the back of my mind. I’m not quite going to argue that thinking in terms of rhizomatic learning helped me settle that much more comfortably into a “guide on the side” mode of reference, but it certainly didn’t seem to hurt. In addition to making more space for the patron to explore at his own pace, I also mentioned my own connection to his paper’s jumping-off point (the 1963 & 1964 Civil Rights actions in St. Augustine, Florida, particularly those targeting the Monson Motor Lodge). This brings rhizomatic learning a bit into the #critlib wheelhouse, for critical librarianship needs to consider these fleeting pedagogical moments.

+ +

While I’ve heard that the claim that “neutral” in library discourse properly refers to issues of access and collection rather than questions of librarian demeanor or information, the notion of “neutrality” more commonly seems taken to mean that librarians should be dispassionate about topics, should aspire to a mask of “objectivity” rather than showing enthusiasm, or that libraries should be considered as containing knowledge that lies magically outside or devoid of politics. In today’s case, my breaking of this “neutral” demeanor just involved sharing familiarity with the events and the spaces—nothing that would cloud the student’s space of making meaning—and it seems like this only reinforced his willingness to be patient while exploring the depths of the JSTOR and ProjectMUSE databases.

+ +
+
    +
  1. +

    Writing this in subjunctive mood was not intended to be clever, but I’m leaving it to show much distance I felt from wanting to decide on an overarching outcome while typing this sentence. 

    +
  2. +
+
+ + + + +
+ + + + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/light-mode-in-progress.html b/light-mode-in-progress.html new file mode 100644 index 000000000..f503a5deb --- /dev/null +++ b/light-mode-in-progress.html @@ -0,0 +1,633 @@ + + + + + + +Light Mode in Progress — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + +

Today—the day after I finished up a “16 weeks condensed into 4” Spanish class—I happened to read some folks on Mastodon talking about light themes on websites.

+ +

I’ve been wanting to add one to my site for years, my brain apparently wanted a project I could reasonably accomplish make noticeable progress toward within a day, and I vaguely remembered having seen other Minimal Mistakes theme users discussing how to implement this.

+ +

Thus far today I’ve managed to have my Jekyll-based site correctly generate two different themes: the dark one I’ve been using for years and another light one that’s basically the default theme with a couple of colors switched out. That’s a success!

+ +

Currently this site defaults to my regular dark theme, but will serve a light theme if it sense that you have “prefers light mode” set in your browser or operating system.

+ +

Today’s work also lays the foundation for adding a toggle. That’s successfully building toward a future success!

+ +

There are going to be some surprises along the way to a fully-featured light mode, such as noticing and also fixing the fact that the Bigfoot pop-up colors aren’t really legible at the moment. I’ll need to figure out how many of these things I can avoid hard-coding in the future. But it’s nice to finally work on it, even if doing so was somewhat of a surprise today.

+ +

Update

+ +

As of 2023-10-12, I’ve mostly fixed the things I had noticed with the theme. (They were inaccessible text and background colors related to footnotes and notices.)

+ +

My next ambitious stretch goal will be to make a few user-selectable themes, like Sarah L. Fossheim has done on their site. I’m also considering a move from Bigfoot to Littlefoot for the fancy pop-up footnotes.

+ + + + +
+ +
+ + + + + + + + + + +
Created:
+ + +
Updated:
+ +
+ + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/links-rhizome/index.html b/links-rhizome/index.html new file mode 100644 index 000000000..30c8198f3 --- /dev/null +++ b/links-rhizome/index.html @@ -0,0 +1,538 @@ + + + + + + +Links Rhizome — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

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

Here are some of the places I’ve popped up online.

+ +

Elsewhere On This Site

+ + + +

Social Media

+ + + +

Professional Presences

+ + + +

Shared Reading

+ + + +

Tinkerings

+ + + + + + +
+ +
+ + + + + + + + + + +
Created:
+ + +
Updated:
+ +
+ + + + +
+ + +
+ + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/links/index.html b/links/index.html new file mode 100644 index 000000000..e54e1f562 --- /dev/null +++ b/links/index.html @@ -0,0 +1,482 @@ + + + + + + +Several Links Galore — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

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

Librarians & Info Science Folks

+ + + +

Additional Academics

+ + + +

Web Design & Software Folks

+ + + +

Insightful People in General (i.e. Productivity or Design)

+ + + +

Organizations, Journals, and Blogs

+ + + + + + +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/monthly-signal-boost/august-2020-monthly-signal-boost.html b/monthly-signal-boost/august-2020-monthly-signal-boost.html new file mode 100644 index 000000000..70643d188 --- /dev/null +++ b/monthly-signal-boost/august-2020-monthly-signal-boost.html @@ -0,0 +1,662 @@ + + + + + + +August 2020 Monthly Signal Boost — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + + + +

Monthly What?

+ +

2020 has not been a kind year. This last month has been hectic and at times very overwhelming. Here’s some of what has worked to keep my spirits up.

+ +

Mindfulness

+ +

I’ve been trying to get back into mindfulness & meditation practices, since I’d like to more skillfully recognize when my mind or emotions wander to realms I’d prefer they not go. It’s also good practice at finding joy in small things, to better recharge and practice the hopefulness necessary to keep doing difficult things.

+ +

I’ve only listened to the first few practices of the Waking Up app by Sam Harris, but it seems like a great fit for anyone interested in mindfulness practices—and particularly anyone of a more analytical bent. Tai chi (offered as P.E. classes at UC Riverside!) was the first way I was able to connect with a mindfulness practice in a sustained way. I think this was largely because the slow physical exercises kept my ADHD tendencies occupied just enough to help me also pay attention to my breath, my sensations, and whatever else entered into my attention. Waking Up is the mindfulness instruction I’ve encountered that’s closest my experience of learning moving mediation though tai chi, largely because of how deftly Harris blends his verbal instructions with periods of silence to help you experience what he presents. I’m not sure yet if a subscription would be right for me, but I definitely recommend trying the first few (free!) days of the app if you’ve been curious about mindfulness. That’s especially true if you’ve tried mindfulness previously but were turned off by some aspects how it was taught. Harris’s approach seems resolutely non-religious and non-spiritual/mystical.

+ +

The Plum Village app, on the other hand, clearly centers mindfulness practices in the engaged Buddhist approach of Thích Nhất Hạnh. The app is entirely free and features guided meditations, other practices, texts, and more from the Plum Village community. If you’ve previously encountered the original version of the app (released back in 2018), the newest versions (up to 2.2 as of mid-August) are greatly expanded and refined. I can’t speculate what it would be like to learn mindfulness or Buddhist practices primarily through this app, but I definitely appreciate what the Plum Village community has made available through it.

+ +

Music

+ +

Love Genius by Sonic D has consistently brought a goofy grin to my face since the first time I heard it. It’s a footwork / bass music version of a Tom Tom Club tune you might recognize through a bunch of songs that sample or remix it—in particular Mariah Carey’s “Fantasy.” You might also dig some of his other stuff, such as what he’s got on Soundcloud or his Math & Science mixes.

+ +

Time Flex is basically a compilation of early releases by John Tejada under the moniker Autodidact. Originally released in 1996 & 1997, these tunes have more of a Warp Records / Polygon Window vibe than Tejada’s later stuff. If you’ve ever wanted something like Polygon Window but with more groove & shuffle, this will be right up your alley.

+ + + + +
+ + + + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/monthly-signal-boost/introducing-monthly-signal-boosts.html b/monthly-signal-boost/introducing-monthly-signal-boosts.html new file mode 100644 index 000000000..fc9939632 --- /dev/null +++ b/monthly-signal-boost/introducing-monthly-signal-boosts.html @@ -0,0 +1,668 @@ + + + + + + +Introducing Monthly Signal Boosts — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + + + +

What’s This About?

+ +

It’s pretty clear that my weekly assemblage posts aren’t particularly sustainable, at least at the moment. All the same, I want to get back to regular posts. With these I aim at boosting—sometimes also critiquing—things that I appreciate.

+ +

Seeing Jessica Schomberg’s Monthly Reading Lists gave me the idea to do a monthly format.

+ +

We’ll see where this goes!

+ +

How Will They Work?

+ +

I’m really good at reading and engaging widely—but I’m not as great at keeping notes or forcing myself to reflect. So I’ll experiment with the exact way I’ll annotate or respond to what I mention in these.

+ +

I’m planning to start a post at the beginning of each month, then edit it throughout the month. So each will be a monthly log, pretty much, of stuff I want to amplify.

+ +

Is That It?

+ +

As I’m writing this introduction to these posts, I’m also working on putting together my dissertation qualifying exam lists. I’m intrigued by the ethos / approach of working in public, so I’m considering doing some sort of “evergreen notes”—most likely a set of pages that I continually edit as I refine ideas, definitions, connections, bibliographies, etc.

+ +

I’m not sure quite yet how that sort of note will live on my site, but again: we’ll find out!

+ + + + +
+ + + + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/monthly-signal-boost/july-2020-monthly-signal-boost.html b/monthly-signal-boost/july-2020-monthly-signal-boost.html new file mode 100644 index 000000000..d15db9269 --- /dev/null +++ b/monthly-signal-boost/july-2020-monthly-signal-boost.html @@ -0,0 +1,666 @@ + + + + + + +July 2020 Monthly Signal Boost — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + + + +

Monthly What?

+ +

Podcasts

+ +

Organizing Ideas Podcast: Episode 20 with Jessica Schomberg Jessica Schomberg talks about their book, other readings they’ve learned from, how workplace improvements for disabled folks will lead to better workplaces for everyone, about relationships and solidarity in library work. It’s a really engaging listen!

+ +

The Latino Card: Episode — Mask-ulinity Talking about different approaches people are taking to social distancing. Discusses ?Tommy Simmons? article at the Idaho Press, which talks about psychology of adhering to government guidelines. How wearing a mask is a signal to the world that COVID19 is a problem & we need to work together on addressing it. Masculinity and admitting vulnerability.

+ +

The Better Bozo: Episode 6 I wasn’t sure about listening to this whole episode for the first few minutes, since it sounded a little too much like listening in on a sporpsball conversation or general talk radio. But it ended up featuring a fascinating discussion about how privileged white guys can get better at asking themselves “who benefits by me staying silent at this moment?”, as well as how to apply organizing principles to help forward collective liberation. One portion that seems particularly relevant to library work is when the guest, Abraham Lateiner of Freedom Beyond!, mentions that it’s important to be attuned to both the macro and micro levels in a situation, as well as the tension between two poles. (Apparently polarity work is an organizing tool?) The main polarized tension he discusses is between challenge and affirmation.

+ +

He uses the example of how America has praised individual freedoms for so long that it’s become incredibly difficult to champion equitable outcomes. As I’m typing this, I can’t help but wonder what an ALA Office of Intellectual Responsibility would look like, or even an ALA Office of Intellectual Equity.

+ +

Articles

+ +

“Starting Points” by Andrew Cooper was written for the Buddhist Peace Fellowship’s Turning Wheel magazine in 1993, on the second anniversary of the beating of Rodney King. Cooper explains, “The question is not whether or not a community is ‘racist’—the question is how this racism operates.” He also quotes a psychiatrist’s explanation that “in the human realm, the law of survival is not kill or be killed; it is define or be defined.”

+ +

I was living in Riverside and in high school for the King verdict and the uprisings, all of which were very much huge local news. Witnessing such a wanton failure of the legal system to produce justice profoundly influenced my understanding of our legal, social, economic, representational, and other systems. This article encapsulates a lot about those systems into surprisingly few words. As we still seek to improve upon these current systems, it’s an article well worth your time.

+ + + + +
+ + + + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/mstile-150x150.png b/mstile-150x150.png new file mode 100644 index 000000000..4a48503d9 Binary files /dev/null and b/mstile-150x150.png differ diff --git a/my-ala-annual-2018-schedule.html b/my-ala-annual-2018-schedule.html new file mode 100644 index 000000000..96bd99711 --- /dev/null +++ b/my-ala-annual-2018-schedule.html @@ -0,0 +1,814 @@ + + + + + + +ALA Annual 2018: My Schedule, Our Notes — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + + + +

#ALAAC2018

+ +

I haven’t been to an Annual ALA Conference yet, so it’ll be interesting to see how my attention can hold up to meeting so many people and hearing so many ideas. I’ve been to a number of smaller conferences, but nothing on this scale.

+ +

Building from the Critical ALA Annual 2018 list of “sessions of possible interest to critical library workers” made by Eamon Tewell and others, here’s a schedule of where I intend to be while in NOLA. I’ll do my best to update this throughout the week, so we can try to meet up if you’d like. Messaging me on Mastodon or Twitter would be great ways to get in touch.

+ +

I’ll do my best to always have an In the Library with the Lead Pipe button on my backpack or lanyard to make it easier to spot me. Please feel free to chat about the journal’s submission or open peer review processes, talk about ideas you have, or anything else. I’ll bring a few buttons with the journal logo’s to give away as well.

+ +

In the Library with the Lead Pipe logo button

+ +

I’ll probably also bring a small number of earplugs. So if you plan to go out dancing or if you see me out somewhere loud, ask and I might have some for you & your ears.

+ +

Group Note-taking > Live Tweeting

+ +

There’s a growing practice of shared note-taking at unconferences and conferences, like at CLAPS2016 and at the #critlib Unconference 2017 in Baltimore. Let’s keep that going and try using more privacy-respecting platforms this time around.

+ +

If you’re interested in helping take group notes—which seem like a more hospitable format than live tweeting for many of us—I’m planning to make publicly-editable Etherpad notes hosted at RiseUp. It’ll be like shared Google Docs, only on a platform that helps avoid Google’s many privacy-destroying tentacles. :octopus: :thumbsdown:

+ +

My plan is to:

+ +
    +
  • + [x] make a pad for each session I'll attend @done +
  • +
  • + [x] give each pad a 1 year lifespan (which anyone can do as they create a pad) @done +
  • +
  • + [x] link to those pads here @done +
  • +
  • +ultimately move our collectively-written notes somewhere else to be determined, such as my site or maybe something like a Sandstorm.io instance for library workers and/or other folks interested in #critlib-type things.1 +
  • +
+ +

If you can think of a better process or make other pads/notes that you want added to shared list, let me know on Mastodon or Twitter!

+ +

Lastly, please: if there’s a microphone, always use the microphone.

+ +

My Schedule

+ +

Thursday

+ +

I’m flying in today—and I wish I could be listening to KEXP’s breakdown of Public Enemy’s It Takes a Nation of Millions to Hold Us Back while in flight. Hopefully they record it or at least spell out the playlist somewhere. Fear of a Black Planet was much more formative for me but I’d love to learn anything I could about the Bomb Squad’s production process for any of their albums.

+ +

I might be down to meet up for vegetarian/vegan food, coffee, or other stuff this evening. Let me know!

+ +

Friday

+ +

In the morning & early afternoon I’ll be exploring NOLA and the convention center.

+ +

1:00p–2:00pm:
+(NMRT) Annual Conference Orientation
+etherpad notes

+ +

4:00pm–5:30pm:
+Opening General Session featuring Michelle Obama
+etherpad notes

+ +

5:30pm–6:30pm:
+Meet the Authors: Mariko Tamaki and Shea Fontana (most likely)

+ +

Saturday

+ +

9:00am–10:00am:
+Making the Framework Work: Adapting the ACRL Framework for Information Literacy in Community College Library Instruction
+etherpad notes

+ +

10:30am–11:30am:
+Student Learning and Information Literacy Committee Discussion Forum
+etherpad notes

+ +

1:00pm–2:30pm:
+(LIRT) Moving Beyond the Threshold: Next Steps in Critical Information Literacy
+etherpad notes

+ +

2:30pm–3:30pm:
+Building Inclusion: How Can Research Instruction at Two-Year Colleges Help Students Successfully Transition to the University?
+etherpad notes

+ +

4:00pm–5:00pm:
+New Librarians on the Block: Early Career Librarianship, Management, and Leadership
+etherpad notes

+ +

Sunday

+ +

9:00am–10:00am:
+High Impact Librarianship: A Showcase of Collaborative and Experiential Learning Initiatives
+etherpad notes

+ +

10:30am–11:30am:
+Whiteness in LIS: Tracing its Impact, Mapping Resistance
+etherpad notes

+ +

12:00pm–1:00pm:
+In the Library in the Lead Pipe meet up in the Networking Uncommons

+ +

2:30pm–3:30pm:
+Breaking Below the Surface of Racism, Whiteness, and Implicit Bias
+etherpad notes

+ +

4:00pm–5:00pm:
+Bridging the Gap: Supporting Subject Liaisons to Become Ambassadors for Digital Scholarship in Academic Libraries
+etherpad notes
+OR
+Neutrality and Its Discontents: Exploring the Ethics of Librarianship in a Partisan World
+etherpad notes
+OR MORE LIKELY
+4:30om–5:30pm:
+Progressive Librarians Guild Meeting

+ +

6:00pm–8:00pm:
+GLBT Round Table Social
+OR
+DSS Social (ACRL DSS)

+ +

8:00pm–??:
+Que(e)ry at ALA New Orleans

+ +

Monday

+ +

9:00am–10:00am:
+Evidence Based Library and Information Practice is…
+etherpad link

+ +

10:30am–11:30am:
+Buried in a “Dying” Field: Pessimism, Uncertain Futures, and the LIS job search
+etherpad link
+OR
+When to Speak Up, When to Listen: Allyship, Race, and Communication in the Academic Library
+etherpad link
+OR
+Open Education Resources (OER): Where Libraries Are and Where We are Going
+etherpad link

+ +

1:00pm–2:00pm:
+Effort, Education, Knowledge, Skill and Teaching Recognized: The READ (Reference Effort Assessment Data) Scale at work in Academic, Public & Special Libraries
+etherpad link

+ +

4:00pm–5:00pm:
+A Library for Everyone: Community Centered Design to Promote Inclusive Librarianship
+etherpad link

+ +

Tuesday

+ +

10:00am–11:30am:
+Closing General Session featuring Viola Davis
+etherpad link

+
+
    +
  1. +

    Making a Sandstorm instance is kind of pie-in-the-sky as a goal for me at the moment, but I can definitely put the notes on my blog at minimum. If you’re interested in helping with a Sandstorm instance for library workers, let’s talk! 

    +
  2. +
+
+ + + + +
+ + + + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/new-site.html b/new-site.html new file mode 100644 index 000000000..46be99afa --- /dev/null +++ b/new-site.html @@ -0,0 +1,653 @@ + + + + + + +New Site — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + +
+

Complicating, circulating…new site, new site.

+
+ +
+

Operating, generating…new site, new site.

+
+ + + +


+ +

Thanks for coming by, and for indulging my Depeche Mode reference.1 This new site is decidedly in an early state of becoming, as I figure out how to use Jekyll and this particular theme.

+ +

I’ll probably use this for more long-form writing and keep the shorter things over at my Tumblr site, Foureyedsoul. The Tumblarians over there are a good bunch—sociable, generous, witty, and insightful. Why not check them out for yourself?

+ +
+
    +
  1. +

    Clicking the title of this post should take you to YouTube, to help you know the song if you’re not already humming along. 

    +
  2. +
+
+ + + + +
+ +
+ + + + + + + + + + + +

+ Tags: + + + + + +

+ + + + + + +
Created:
+ + +
Updated:
+ +
+ + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/ADHD-tech/about-ADHD-technologies.html b/notes/ADHD-tech/about-ADHD-technologies.html new file mode 100644 index 000000000..765bd2faf --- /dev/null +++ b/notes/ADHD-tech/about-ADHD-technologies.html @@ -0,0 +1,584 @@ + + + + + + +About ADHD technologies — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + ADHD tech / + + + + about ADHD technologies + + +
+ + +
Created: +
+ + +
Updated: +
+ + +

Note status: :seedling:

+ + +
+ +

I recently saw this tweet by Aimi Hamraie, with the hashtag ADHDtechnologies:

+ + + + +

…so I figure that this wiki is a great venue to share some of the ADHD technologies I use.

+ +
+ + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ +
+ + + + + + + + + + +
+ Created: +
+ + +
+ Updated: +
+ +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/ADHD-tech/apple-watch-ADHD.html b/notes/ADHD-tech/apple-watch-ADHD.html new file mode 100644 index 000000000..5b9e906d2 --- /dev/null +++ b/notes/ADHD-tech/apple-watch-ADHD.html @@ -0,0 +1,650 @@ + + + + + + +Apple Watch ADHD — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + ADHD tech / + + + + apple watch ADHD + + +
+ + +
Created: +
+ + +
Updated: +
+ + +

Note status: :herb:

+ + +
+ +

I’ve been wanting to write about some ways that my smartwatch has helped me deal with the fact that I perceive time differently than most neurotypical people. It’s an example of what Aimi Hamraie has called “ADHD technologies.”1

+ +

Timers

+ +

I use the timer function often—especially when I’m doing any kind of presentation, instruction, or other public speaking. Timers are actually one of the main reasons I initially saved up for my smartwatch. I’d previously used my phone as a timer, only to be occasionally chided by instructors that they found my “checking my phone” during instruction sessions distracting.2

+ +

The two most obvious benefits of a smartwatch timer:

+
    +
  1. it can silently and insistently inform you when your timer is up
  2. +
  3. it uses the cultural assumption that if you glance at an electronic device on your wrist, you’re checking about time
  4. +
+ +

Timer Apps

+ +

Here are the timer apps I use the most:

+ +
    +
  1. Apple’s built-in timer is great and displays well in many different faces
  2. +
  3. +Due lets you have multiple timers simultaneously. +
      +
    • For instance, you can set a 2 hour timer in Due to remind you of when you need to start making dinner. Then simultaneously you can set a 25 minute timer in Due to keep track of a pomodoro burst of work/focus. On days when you’re really scattered, you can even set smaller simultaneous 5 or 10 minute timers to help remind you to stay on task.
    • +
    • Due also can sync between your watch, phone, and computer. Super handy in case you’re not always at your computer!
    • +
    +
  4. +
  5. +Time Timer is one that I’ve just started using in the last few days. It displays time “backwards,” by highlighting the time remaining rather than the time elapsed. The same company makes a range of physical timers as well. This app version is currently free during the pandemic. I tend to get up and walk around when I’m thinking. Sometimes it’s to get the wiggles out, sometimes because I truly get distracted, and sometimes because I go look through my bookshelves trying to find a book related to an idea I just had. So for me, a timer strapped to my wrist feels far lot more reliable than a physical one.
  6. +
+ +

Calendars & Time

+ +

Here are some things I’ve found about setting up the basic look of the watch, outside of timers or other functions.

+ +

Built-in Watch Features

+
    +
  • putting the date prominently with one of the large complications
  • +
  • using the “World Clock” to display digital time in analog faces
  • +
+ +

Other Apps

+ +
    +
  • +watchsmith’s week & geometry elements +
      +
    • “Week 32” week number complication
    • +
    • Geometric representation of the year, highlight today’s dot out of 365 dots in 12 rows… i.e. a geometric representation of the day, which lets me perceive the relative proportions of elapsed and remaining time way better than just looking at the representation “August 27” ever could
    • +
    +
  • +
  • upcoming calendar events in complications
  • +
+ +
+

Changes I Forsee / Todo

+ +- [ ] add images
+   - [ ] Watchsmith's week number
+   - [ ] Watchsmith's geometric calendar
+- [ ] decide if I want to split this into smaller notes
+
+
+
    +
  1. +

    For more on that, check out my About ADHD technologies note. 

    +
  2. +
  3. +

    Yes, there are more levels to that than I care to go into here. 

    +
  4. +
+
+ +
+ + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ +
+ + + + + + + + + + +
+ Created: +
+ + +
+ Updated: +
+ +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/ADHD-tech/index.html b/notes/ADHD-tech/index.html new file mode 100644 index 000000000..d43596f4d --- /dev/null +++ b/notes/ADHD-tech/index.html @@ -0,0 +1,536 @@ + + + + + + +ADHD tech — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+
+ + + + + +
+ + + + + + + + + +
+ +
+

ADHD tech +

+ + + +
+ + +
+ + + + +
+ +
+
a wonky wiki, a digital garden
+
+
+ +
+ + home / + + + notes / + + + + ADHD tech / + + + + index + + +
+ + + +

Pinned ADHD tech notes

+ + + + +

All ADHD tech items

+ + + + + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + + +
+ +
+ + + + + + +
+ Created: +
+ + +
+ + + +
+ + +
+ + + +
+
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/ADHD/index.html b/notes/ADHD/index.html new file mode 100644 index 000000000..5306d259b --- /dev/null +++ b/notes/ADHD/index.html @@ -0,0 +1,503 @@ + + + + + + +ADHD — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+
+ + + + + +
+ + + + + + + + + +
+ +
+

ADHD +

+ + + +
+ + +
+ + + + +
+ +
+
a wonky wiki, a digital garden
+
+
+ +
+ + home / + + + notes / + + + + ADHD / + + + + index + + +
+ + + + + +

All ADHD items

+ + +

There's nothing here yet!

+ + + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + + +
+ +
+ + + + + + +
+ Created: +
+ + +
+ + + +
+ + +
+ + + +
+
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Accessibility/index.html b/notes/Accessibility/index.html new file mode 100644 index 000000000..7af8aa369 --- /dev/null +++ b/notes/Accessibility/index.html @@ -0,0 +1,512 @@ + + + + + + +Accessibility — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+
+ + + + + +
+ + + + + + + + + +
+ +
+

Accessibility +

+ + + +
+ + +
+ + + + +
+ +
+
a wonky wiki, a digital garden
+
+
+ +
+ + home / + + + notes / + + + + Accessibility / + + + + index + + +
+ + + + + +

All Accessibility items

+ + + + + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + + +
+ +
+ + + + + + +
+ Created: +
+ + +
+ + + +
+ + +
+ + + +
+
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Accessibility/math-a11y.html b/notes/Accessibility/math-a11y.html new file mode 100644 index 000000000..f94a04072 --- /dev/null +++ b/notes/Accessibility/math-a11y.html @@ -0,0 +1,651 @@ + + + + + + +Math Accessibility — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + Accessibility / + + + + math a11y + + +
+ + +
Created: +
+ + +
Updated: +
+ + +

Note status: :seedling:

+ + +
+ +

Assumed audience People relatively—or almost entirely—new to web publishing

+ +

I’ve lately done some work to improve the accessibility of math notation (equations, symbols, etc.) for users of screen readers online, particularly for the creation of open educational resources (OER). It’s been an unexpectedly engrossing investigation, so I figured I’d share what I’ve learned so far—in particular, the workflow I’d recommend for others.

+ +

Our Problem: Math Online Ain’t Easy

+ +

In the recent past, at least at the places I know best, math educators have heavily relied on images or handouts instead of considering “online first” or born accessible publishing and formatting. I’m not sure how faculty and staff handled the creation of accessible equivalents, although I imagine they mostly relied on the expertise of Disability Services to make things accessible for the students who had accommodations. That’s an understandable approach, coming from a perspective where typesetting and other formatting intricacies are handled by a publisher or dedicated student support staff.

+ +

My perspective is slightly different. My critical media studies background tells me that formats imply politics, and my interest in accessibility similarly asks questions like “who is included by default?”, “what interactions does this enable?”, and “which people does this disable?”

+ +

Thankfully, the math educators I know who are interested in OER share similar concerns. They also feel that OER has the potential to liberate their pedagogy—which will include learning aspects of formatting and accessibility, to create materials that anticipate a larger and more inclusive set of learners.

+ +

One common way of writing math is in LaTeX. (If you’re unfamiliar, Using LaTeX in Pressbooks provides a nice, very “non-specialist” overview.) Unfortunately, while LaTeX has become a standard way of writing and typesetting math, it was created with typesetting in mind, and largely prioritizes PDF creation. It doesn’t inherently provide much for screenreader technologies.

+ +

Although work is being done to make LaTeX output more accessible, even the most recent things I’ve found centers on making well-tagged PDFs. That’s laudable work! PDFs aren’t an ideal format for OER, however. By design, the content of PDFs are not open and editable. As an open, editable standard, HTML makes much more sense for OER creation and dissemination, even before factoring in accessibility concerns.

+ +

An Online-First Approach

+ +

Now that we’ve thanked LaTeX for its contributions to typesetting and realized we need something better-equipped for web pages, let’s get acquainted with two new friends: MathML and MathJax.

+ +

MathML is a project of the W3C’s Math Working Group, who’ve been working to make math accessible online since 1996! Without getting too far into the weeds, MathML and HTML use a similar approach to authoring. Each surrounds content with tags that add information, with that information interpreted by web browsers: <tags>content</tags>.1

+ +

This tag-based approach makes MathML somewhat verbose.2 It also introduces an astronomical capacity for user error and makes authoring MathML without a dedicated editor cumbersome at best. Thankfully, the W3C’s list of equation editors annotates the tools that recognize handwriting. Without needing to learn the actual underlying syntax, you can use your touchpad or mouse to “draw” the equation, which one of these tools will convert into valid MathML code.

+ +

Firefox and Safari currently have the best built-in support for MathML, but Chrome and Edge don’t display it automatically.3 To solve this problem, we can use our new friend MathJax.

+ +

MathJax uses JavaScript to display math in any browser, allowing even holdouts like Chrome or Edge to join in the fun. The project website will let you know far more about it than I could, both in terms of its accessibility features and its customizations for input and output. For our purposes, the essential takeaway is that by copying and pasting another HTML <tag> into a webpage, you can instruct any web browser to load MathJax, then display math content correctly both for sighted learners and learners who use screenreader technologies.

+ +

If you want to learn more, the best single-page explanation of MathML and MathJax I’d found was written by the Accessibility and Usability folks at Penn State.

+ +

A Workflow for Online Math

+ +

Okay! Now that we understand the role of MathML and MathJax, what’s the fastest way to make math accessible online?

+ +

Having tested different options in Pressbooks and LibGuides, here’s what I suggest:

+ +
    +
  1. Use one of the authoring tools in the W3C’s list of equation editors that recognizes handwriting to create the MathML code from what you write using a trackpad or mouse. You might try MyScript Math or MathType.
  2. +
  3. Copy that MathML code into the “text” or “code” or “source” view of your web-authoring platform (like Pressbooks or LibGuides).
  4. +
  5. Add the MathJax script code, also in the “text” or “code” or “source” view. +
      +
    • You might use the code under the “Using MathJax version 3” heading on MathJax’s own “Getting Started” page or the code under the “Add MathJax in an HTML Document” section of the PennState page. The version I recently tested in Pressbooks and LibGuides was from the PennState page.
    • +
    • You’ll only need to add this <script> code once per page, not once per section of <math> code.
    • +
    • If you’re displaying math on many pages, you might want to have that script tag automatically included in whatever platform you’re using. Usually things like this are included in the <head> section of a web page. +
        +
      • LibGuides has an interface for this, at least for administrators.
      • +
      • Static site generators like Jekyll often do this using includes.
      • +
      • It doesn’t seem possible in Pressbooks, from a quick skim of their Network Manager Guide and User Guide, but their support certainly should be able to give you a more definitive answer than my 3 minute search.
      • +
      +
    • +
    +
  6. +
  7. Test in Chrome and Edge (the browsers most likely to not support MathML directly), as well as Firefox and Safari.
  8. +
  9. +Optional but Highly Recommended: Grumble about Chrome and Edge developers not building accessibility support directly into their browser.
  10. +
+ +

For Authors Who Already Know LaTeX

+ +

If you’re working with an author who already knows LaTeX—or if you know it yourself—there’s still good news! The W3C lists many LaTeX to MathML converter tools, as well as converters for other systems like ASCIIMath or different types of scientific computation.

+ +

For you, “Step 1” of the above workflow would instead be “use a converter to generate the MathML code”. You’ll still want to add MathJax to your page, then test it in (and perhaps grumble about) various browsers.

+
+
    +
  1. +

    We’ve arrived at a point in the conversation where someone might push up their glasses, smile, and launch into a well-meaning tangent about how MathML is a type of XML. But let’s choose to just point out that impressive, inviting, and/or intimidating patch of weeds, then move right along. 

    +
  2. +
  3. +

    The code for this three-line proof of the Pythagorean theorem starts at line 27 of the page’s source code

    +
  4. +
  5. +

    Two excellent places to find up-to-date info on browser support are Mozilla’s MDN, where browser support is usually listed at the bottom of each page, and Can I Use

    +
  6. +
+
+ +
+ + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ +
+ + + + + + + + + + +
+ Created: +
+ + +
+ Updated: +
+ +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Keywords/index.html b/notes/Keywords/index.html new file mode 100644 index 000000000..2fe85aee6 --- /dev/null +++ b/notes/Keywords/index.html @@ -0,0 +1,520 @@ + + + + + + +Keywords — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+
+ + + + + +
+ + + + + + + + + +
+ +
+

Keywords +

+ + + +
+ + +
+ + + + +
+ +
+
a wonky wiki, a digital garden
+
+
+ +
+ + home / + + + notes / + + + + Keywords / + + + + index + + +
+ +

All Keywords folders

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

Pinned Keywords notes

+
    + +
+ + + +

All Keywords items

+ + +

There's nothing here yet!

+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + + +
+ +
+ + + + + + +
+ Created: +
+ + +
+ + + +
+ + +
+ + + +
+
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Listening/index.html b/notes/Listening/index.html new file mode 100644 index 000000000..1447edb14 --- /dev/null +++ b/notes/Listening/index.html @@ -0,0 +1,529 @@ + + + + + + +Listening — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+
+ + + + + +
+ + + + + + + + + +
+ +
+

Listening +

+ + + +
+ + +
+ + + + +
+ +
+
a wonky wiki, a digital garden
+
+
+ +
+ + home / + + + notes / + + + + Listening / + + + + index + + +
+ +

Welcome to my Listening notes!

+ + + + + + +

All Listening items

+ + +

There's nothing here yet!

+ + + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + + +
+ +
+ + + + + + +
+ Created: +
+ + +
+ + + +
+ + +
+ + + +
+
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Note-taking/Approaches/casey-boyle-something-like-reading-ethics.html b/notes/Note-taking/Approaches/casey-boyle-something-like-reading-ethics.html new file mode 100644 index 000000000..4d079cf7f --- /dev/null +++ b/notes/Note-taking/Approaches/casey-boyle-something-like-reading-ethics.html @@ -0,0 +1,612 @@ + + + + + + +Casey Boyle’s …something like a reading ethics… — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + Note taking / + + + + Approaches / + + + + casey boyle something like reading ethics + + +
+ + +
Created: +
+ + +
Updated: +
+ + +

Note status: :seedling:

+ + +
+ +

This strategy for reading is meant to build better habits of reading, as well as better note-taking. It’s a nice complement to a rhetorical-precis, but more open-ended.

+ +

Casey Boyle’s “…something like a reading ethics…”

+ +

Casey’s post on his approach (via the WaybackMachine) explains it in excellent detail. It’s very much worth reading in full.

+ +

Here’s just the brief summary he provides, both for reading and note-taking:

+ +

Reading

+ +
    +
  1. Skim through the work noting the title, chapter, subtitles, indices, etc.
  2. +
  3. Read the introduction & conclusion
  4. +
  5. Fill in the rest by reading through the work
  6. +
+ +

Note-Taking

+ +
    +
  1. Exigence (identify the writer’s articulation of the exigence)
  2. +
  3. Response (identify what the writer is bringing in response to exigence). 
  4. +
  5. Key Terms/Words (locate the key terms and concepts)
  6. +
  7. Key Citations (3-4 key citations the work relies on)
  8. +
  9. Questions (understanding and critique)
  10. +
  11. Speculative Response (speculate how a writer might respond to Questions in Step 5).
  12. +
+ +
+ + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ +
+ + + + + + + + + + +
+ Created: +
+ + +
+ Updated: +
+ +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Note-taking/Approaches/index.html b/notes/Note-taking/Approaches/index.html new file mode 100644 index 000000000..4df3199a8 --- /dev/null +++ b/notes/Note-taking/Approaches/index.html @@ -0,0 +1,524 @@ + + + + + + +Approaches — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+
+ + + + + +
+ + + + + + + + + +
+ +
+

Approaches +

+ + + +
+ + +
+ + + + +
+ +
+
a wonky wiki, a digital garden
+
+
+ +
+ + home / + + + notes / + + + + Note taking / + + + + Approaches / + + + + index + + +
+ + + + + +

All Approaches items

+ + + + + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + + +
+ +
+ + + + + + +
+ Created: +
+ + +
+ + + +
+ + +
+ + + +
+
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Note-taking/Approaches/rhetorical-precis.html b/notes/Note-taking/Approaches/rhetorical-precis.html new file mode 100644 index 000000000..80d8772bc --- /dev/null +++ b/notes/Note-taking/Approaches/rhetorical-precis.html @@ -0,0 +1,618 @@ + + + + + + +Rhetorical Précis — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + Note taking / + + + + Approaches / + + + + rhetorical precis + + +
+ + +
Created: +
+ + +
Updated: +
+ + +

Note status: :seedling:

+ + +
+ +

One of the most frustrating things about reading widely is the situation where you’ve read something, but can’t recall any details or situate that piece among the other things you’ve read.

+ +

As with Casey Boyle’s “…something like a reading ethics…,” writing a rhetorical précis is a great, brief method for engaging with what you read. casey-boyle-something-like-reading-ethics

+ +

Rhetorical Précis

+ +

As the name implies, a rhetorical précis focuses not just on the content of the text, but also on its rhetorical occasion. I feel like I learned this structure—or one quite similar—sometime in high school or undergrad. When digging around for it online years ago, I found a nice, brief explanation from someone who taught Philosophy at Oregon State. Here’s their rhetorical précis format overview, courtesy of the WaybackMachine (since it doesn’t still seem to be readily available at Oregon State’s site).

+ +

Rhetorical Précis Structure

+ +

Here’s the structure of it, taken from Oregon State. (Their page does have a nice example, so it’s still worth clicking through!)

+ +
    +
  1. In a single coherent sentence give the following: +
      +
    • name of the author, title of the work, date in parenthesis;
    • +
    • a rhetorically accurate verb (such as “assert,” “argue,” “deny,” “refute,” “prove,” disprove,” ”explain,” etc.);
    • +
    • a that clause containing the major claim (thesis statement) of the work.
    • +
    +
  2. +
  3. In a single coherent sentence give an explanation of how the author develops and supports the major claim (thesis statement).
  4. +
  5. In a single coherent sentence give a statement of the author’s purpose, followed by an “in order” phrase.
  6. +
  7. In a single coherent sentence give a description of the intended audience and/or the relationship the author establishes with the audience.
  8. +
+ +

Rhetorical Précis Template

+ +

Here’s my condensed version of that structure, suitable for a file template or code editor snippet:

+ +
+

{ author }’s { format }, { title } (date), { verb } { major claim }. { how supports major claim }. { author’s purpose }, in order to { desired intervention }. { description of and/or author’s relationship with intended audience }.

+
+ +
+ + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ +
+ + + + + + + + + + +
+ Created: +
+ + +
+ Updated: +
+ +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Note-taking/Dendron/beginning-to-use-dendron.html b/notes/Note-taking/Dendron/beginning-to-use-dendron.html new file mode 100644 index 000000000..95b5a4712 --- /dev/null +++ b/notes/Note-taking/Dendron/beginning-to-use-dendron.html @@ -0,0 +1,606 @@ + + + + + + +Beginning to Use Dendron — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + Note taking / + + + + Dendron / + + + + beginning to use dendron + + +
+ + +
Created: +
+ + +
Updated: +
+ + +

Note status: :seedling:

+ + +
+ +

What is Dendron?

+ +

Dendron lets you create—and more importantly, organize—plain text notes in VS Code. It not only lets you link between notes like a wiki, it makes notes findable through a tree view and customizable, hierarchical organization.

+ +

I’m such a fan that I switched from Atom to VS Code as my main text editor, happily donate a few dollars a month to support its open-source development, and volunteer as a Dendrologist, helping answer questions and refine documentation.

+ +

Before using Dendron, I’ve long taken notes in Markdown, and I’m familiar with making websites using Jekyll. These experiences make Dendron more intuitive for me than it might be for many new users.

+ +

So here are a few starting points that might make starting out with Dendron easier for you.

+ +

Starting Points

+ +

Kevin and Jonathan presented on Dendron to VS Code’s developer community. This video provides a good overview of what the tool looks like, so you can quickly see if it might suit how you like to work.

+ +

Ian Jones has made a short, free guide on Egghead.io with video instructions to walk you through installing VS Code, installing the Dendron extension, and setting it up for the first time.

+ +

Here’s Dendron’s own Getting Started Guide, which is a combo of text and short videos in their wiki.

+ +

Bryan Jenks has made a robust video introduction, which covers many of the details.

+ +

Other Relevant Notes

+ +

VS Code note

+ +
+ + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ +
+ + + + + + + + + + +
+ Created: +
+ + +
+ Updated: +
+ +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Note-taking/Dendron/index.html b/notes/Note-taking/Dendron/index.html new file mode 100644 index 000000000..1efecc00c --- /dev/null +++ b/notes/Note-taking/Dendron/index.html @@ -0,0 +1,532 @@ + + + + + + +Dendron — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+
+ + + + + +
+ + + + + + + + + +
+ +
+

Dendron +

+ + + +
+ + +
+ + + + +
+ +
+
a wonky wiki, a digital garden
+
+
+ +
+ + home / + + + notes / + + + + Note taking / + + + + Dendron / + + + + index + + +
+ + + + + +

All Dendron items

+ + + + + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + + +
+ +
+ + + + + + +
+ Created: +
+ + +
+ + + +
+ + +
+ + + +
+
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Note-taking/Dendron/literature-notes-dendron.html b/notes/Note-taking/Dendron/literature-notes-dendron.html new file mode 100644 index 000000000..17803a06a --- /dev/null +++ b/notes/Note-taking/Dendron/literature-notes-dendron.html @@ -0,0 +1,607 @@ + + + + + + +Literature Notes in Dendron — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + Note taking / + + + + Dendron / + + + + literature notes dendron + + +
+ + +
Created: +
+ + +
Updated: +
+ + +

Note status: :seedling:

+ + +
+ +

I’ve been refining a system for taking literature notes in Dendron, which complements keeping citations with Zotero. My systems remain perpetually in flux, but this is at least my most current write-up, if not my most current approach.

+ +

Dendron is an extension for the text editor VS Code. If you prefer a “what you see is what you get” tool, you might prefer a note-taking alternative like Zettlr or Obsidian. But if you appreciate the extensibility and customization enabled through VS Code’s vast set of extensions, Dendron’s the best note-taking tool I’ve seen yet. Here’s more on beginning-to-use-dendron.

+
    +
  • Zotero is a free citation manager. Although I’ve used alternatives years ago, I can’t imagine ever moving away from Zotero.
  • +
+ +

Literature Notes

+ +

What’s a literature note? Sönke Ahrens, the author of How to Take Smart Notes suggests splitting your references and your notes.

+ +

He actually suggests a few levels of notes:

+
    +
  1. +Fleeting notes: records of your thoughts written anywhere that’s ready-to-hand; you’ll go through these later to see what’s worth putting into a more permanent system
  2. +
  3. +Literature notes: very short, selective notes about what you read, written primarily in your own words. He suggests keeping these, along with the bibliographic information, in a single place.
  4. +
  5. +Permanent notes: longer notes written as a method of processing your fleeting notes & your literature notes, with an eye toward your own purposes.
  6. +
+ +

Ahrens suggests making links between permanent notes, which is something Dendron is designed to do.

+ +

Dendron’s Structure

+ +

I plan to write more about structuring these literature notes in Dendron.

+ + +
+ + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ +
+ + + + + + + + + + +
+ Created: +
+ + +
+ Updated: +
+ +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Note-taking/Dendron/task-tracking-in-dendron.html b/notes/Note-taking/Dendron/task-tracking-in-dendron.html new file mode 100644 index 000000000..56424c197 --- /dev/null +++ b/notes/Note-taking/Dendron/task-tracking-in-dendron.html @@ -0,0 +1,623 @@ + + + + + + +Task Tracking in Dendron — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + Note taking / + + + + Dendron / + + + + task tracking in dendron + + +
+ + +
Created: +
+ + +
Updated: +
+ + +

Note status: :seedling:

+ + +
+ +

My notes in Dendron are an unruly, monstrous hybrid of a bullet journal, a log, a set of resources, and other information. And I like it like that! They’re a continuation of the monthly planning files I used before Dendron came along.

+ +

So if I use Dendron as a combination attention and task management tool, how does the task management work? I’m glad you asked!

+ +

Tasks, Todos, Task Notes

+ +

I use a mix of inline checkboxes and separate Dendron task notes, pretty much as Dendron suggests. I also really like Mihai Constantin’s BuJo extension for VSCode.

+ +

I’ll make a dedicated task note for anything I’d mention to someone else. This might be “write rough draft of conference presentation” or “do Saturday chores.” Each of these is a bundle of smaller tasks. Each also might be one mile marker (or other chunk of progress) toward a larger project.

+ +

Inline notes are basically anything that I feel like writing down as a step to something. These can be sprinkled throughout any note, and in particular will be on dedicated task notes.

+ +

It’s dangerous to sprinkle inline tasks too freely among different notes, since that makes them increasingly difficult to find. That’s part of why dedicated task notes are important… but even more important are regular reviews. (Doing regular reviews is a difficult practice to do consistently—but it’s profoundly rewarding, so I do my best.)

+ +

Inline Todo-Tracking

+ +

For inline todos, I mostly use Markdown checkboxes, which look like - [ ] when they’re yet to be done, and - [x] when they’re done. Most Markdown rendering engines will display those as something like :black_medium_square: or :ballot_box_with_check:.

+ +

I use the BuJo extension’s Bullet Journal symbols to indicate the status of these inline tasks, with two small differences in interpretation.

+ +

To my mind, “dropped” is ambiguous. I prefer a clear distinction between “oops, I didn’t do this” and “This was intentionally cancelled (whether by me or someone else).” Second, I see events as types of actions. After all, I do have to either attend them or not! So I don’t use - [<] to mean “migrated backward”. Intead, it means “intentionally not done.” (I plan to eventually change to just using -[o] and editing the styles, but at the moment, editing the styles for this one notation seems to be broken.)

+ +

Task Notes

+ +

With Dendron, task notes can display extra information in various views. This information lives in the YAML header of a note.

+ +

As of 2022-10, I’ve been using two naming patterns to extend these features of Dendron. Since Dendron uses hierarchical naming conventions to create “nodes,” I use tp and ta to indicate tasks-project and tasks-archive.

+ +

Other Relevant Notes

+ +

all my notes on Dendron
+vs-code-snippets

+ +
+ + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ +
+ + + + + + + + + + +
+ Created: +
+ + +
+ Updated: +
+ +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Note-taking/Obsidian/beginning-to-use-obsidian.html b/notes/Note-taking/Obsidian/beginning-to-use-obsidian.html new file mode 100644 index 000000000..533783943 --- /dev/null +++ b/notes/Note-taking/Obsidian/beginning-to-use-obsidian.html @@ -0,0 +1,604 @@ + + + + + + +Beginning to Use Obsidian — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + Note taking / + + + + Obsidian / + + + + beginning to use obsidian + + +
+ + +
Created: +
+ + +
Updated: +
+ + +

Note status: :seedling:

+ + +
+ +

What is Obsidian?

+ +

Well, it’s complicated.

+ +

And so are my feelings.

+ +

The simple version is that Obsidian is an app that lets you write linked notes, mostly in Markdown format, and can render dynamically-updated sections of those notes.

+ +

This last piece—the dynamic updating—is what makes it compelling and complicated.

+ +

The best example, and the one that’s made me largely move my digital bullet journal away from VSCode & Dendron (see Task Tracking in Dendron for more info) is the Tasks plugin. With this plugin, you can set up queries in your notes that will dynamically search from & render info stored in other notes. This is really substantial for Markdown notes, which are effectively just plain text. (Plain text is the cicada of file formats; files in plain text will still be around long after any of us.)

+ +

However, Tasks is a volunteer-run plugin. It’s already on its second (and, frankly, amazing) maintainer.

+ +

Getting the queries to show up in new notes the way I want them to (i.e. in daily, weekly, monthly, etc. files) requires another couple plugins, one of which is actively maintained and the other of which isn’t.

+ +

Even though Obsidian has taken off so rapidly that there’s an enticingly-slash-infuriatingly fertile ecosystem of boosters and people writing paywalled guides, I’ve already run into concerns about whether the plugins that make it thrive will be maintained long-term.

+ +

Will Obsidian’s main developers take on the task of maintaining the most-used plugins, if and when these plugins’ individual maintainers can’t continue? That’s my largest question—and it grows more crucial the longer that Obsidian’s fire consumes the oxygen found in the “Markdown, with extra features” space.

+ +

For now, Obsidian solves the biggest hurdle I’ve found with VSCode. I’m happy with my current set-up, and extremely happy with the fact that the various third-party plugins have finally helped me make smooth the sharpest edges off my long-running attempts to handle tasks with text files.

+ +

So I’ll detail my approach in a few notes here, and refine or augment these notes as I keep learning more. But please regard this more as ongoing experimentation rather than enthusiastic endorsement. I want to love Obsidian as much as its many acolytes do, but I’m approaching it cautiously.

+ +
+ + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ +
+ + + + + + + + + + +
+ Created: +
+ + +
+ Updated: +
+ +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Note-taking/Obsidian/index.html b/notes/Note-taking/Obsidian/index.html new file mode 100644 index 000000000..2677c5df7 --- /dev/null +++ b/notes/Note-taking/Obsidian/index.html @@ -0,0 +1,532 @@ + + + + + + +Obsidian — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+
+ + + + + +
+ + + + + + + + + +
+ +
+

Obsidian +

+ + + +
+ + +
+ + + + +
+ +
+
a wonky wiki, a digital garden
+
+
+ +
+ + home / + + + notes / + + + + Note taking / + + + + Obsidian / + + + + index + + +
+ + + + + +

All Obsidian items

+ + + + + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + + +
+ +
+ + + + + + +
+ Created: +
+ + +
+ + + +
+ + +
+ + + +
+
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Note-taking/Obsidian/obsidian-plugins.html b/notes/Note-taking/Obsidian/obsidian-plugins.html new file mode 100644 index 000000000..b823845ef --- /dev/null +++ b/notes/Note-taking/Obsidian/obsidian-plugins.html @@ -0,0 +1,676 @@ + + + + + + +Obsidian Plugins — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + Note taking / + + + + Obsidian / + + + + obsidian plugins + + +
+ + +
Created: +
+ + +
Updated: +
+ + +

Note status: :herb:

+ + +
+ +

Assumed audience People at least passably familiar with Obsidian. See my other notes on Obsidian for more context.

+ +

What’s the Big Deal about Obsidian Plugins?

+ +

One of the best—and most anxiety-producing, from the viewpoint of long-term stability—aspects of Obsidian is how the developers have opened up the app to community plugins. These plugins extend the core behaviors in various ways.

+ +

While your notes are ultimately just a bunch of Markdown files, the plugins can perform so-called “dynamic queries”. In hopefully simpler terms, the plugins let you add instructions to the “source code” of the note that tell the plugin to query, or search for something (like search for tasks in some or all of your notes), and these instructions can be rendered dynamically, or on the fly, differently in the “reading view” or “live preview” of the note (like actually showing the list of tasks you’ve specified in your query).

+ +

For example, if the “source code” of a note contains the following instructions:

+
```tasks 
+not done 
+starts before tomorrow
+(tags do not include #waiting)
+group by happens
+```
+
+ +

Then the “reading view” or “live preview” of the note can display a list of tasks from any of your Obsidian notes, nicely grouped together by day, and with optional links back to the original note that contains the task.

+ +

Here is an example with five different tasks, grouped into headings under three different days:
+five example tasks, each about writing a set of clever task examples

+ +

This means your notes can take on the behavior of databases or task-management systems—yet still retain all the cross-app portability and longevity of text files!

+ +

My Shortlist

+ +

When I first looked at Obsidian years ago, I was frustrated by the lack of obvious ways to customize the look, feel, and behavior. Both for better and for worse, the app’s core developers have allowed community members to create plugins. This is great in terms of allowing for a wider variety of customizations than a small handful of official developers can support. But it’s simultaneously worrisome to have some of the most crucial elements of my everyday experience be outsourced to volunteers in the community.

+ +

In any event, I figured I’d write a list of some of the plugins I find most essential for my own experience as I’m beginning to use Obsidian, in case it helps save other people frustration in setting up Obsidian to work for them.

+ +

Here’s an alphabetical list of the Obsidian plugins I rely on most frequently.

+ +
    +
  • Linter
  • +
  • Periodic Notes
  • +
  • Style Settings
  • +
  • Tasks
  • +
  • Templater
  • +
+ +

Linter

+ +

You might be familiar with the concept of a linter if you’ve used code editors. Linters are handy for keeping things tidy & presentable by enforcing stylistic preferences, such as whether to automatically delete all whitespace at the end of a line of text or to use tabs or spaces when indenting.

+ +

Victor Tao’s Linter plugin applies this type of automatic formatting and stylization to your notes in Obsidian. I have it set to lint on save, to make sure that heading levels in a note only increase by a single level at a time, and do similar types of chores that automatic processes will almost always be better at than humans.

+ +

Timestamps are by far the most important of these actions for me. I want my notes to be as self-contained and usable within and outside of Obsidian as possible, so I want to be able to easily see when a note was last updated from within the note itself, rather than relying on tools like operating system file info panels.

+ +

The plugin’s YAML Timestamp rule handles this wonderfully. I use both a created and a modified key for this. And since ISO 8601 is the correct (and XKCD-approved!) format for all things time-y, the specific formatting string I use is:
+YYYY-MM-DD[T]HH:mm:ss[-06:00].
(If you’re not also in Mountain Time, you’d probably want to change the [-06:00] offset there. But hey, you do you!)

+ +

It’s even possible to apply “lint on save” even on mobile! “Mobile” is the first item in the settings menu of the Mobile app, and it lets you manage the toolbar options available in the mobile app. I’ve made the first one be “Save current file.” I don’t know if it’s possible to apply an icon there, but having it first is easy to enough to remember.

+ +

Here’s the plugin’s website and its GitHub repository.

+ +

Style Settings

+ +

This one is made by Matthew Meyers, who has made a number of other Obsidian plugins. It’s known on GitHub as Obsidian Style Settings and is listed within the app itself just as Style Settings.

+ +

Other themes, such as Chris Geiser’s Shimmering Focus, rely on it as a common interface for their own theme settings.

+ +

Depending on the theme, this plugin will allow you to specify things like various colors, fonts, font sizes, how backlinks are displayed, and whether to hide or display entire sections of the app interface. For instance, I mostly use the Shimmer Focus theme, but as seen in the screenshot at the first section of this note, I’ve changed the font and colors to be closer to Daybreak, my preferred theme.

+ +

Periodic Notes

+ +

Obsidian has a built-in Daily notes plugin, which might be sufficient for many people.

+ +

Liam Cain’s Periodic Notes plugin adds the ability to create weekly, monthly, quarterly, or yearly notes, each with different templates. You can see and navigate these in the Calendar pane, and even create new ones directly by clicking on that day or week.

+ +

You can customize the format for note titles at each level, as well as other settings. I’ll likely make a separate note detailing how I have this plugin set up eventually.

+ +

Tasks

+ +

Originally written by Martin Schenck and now expertly maintained by Clare Macrae, the Tasks plugin is honestly what made me ultimately switch from Dendron to Obsidian for the bulk of my notes.

+ +

It lets you track and display tasks in various ways. The example above provides a quick overview of what it can do. For more of how I use it, check out my obsidian-tasks-plugin-patterns note.

+ +

Beyond that, for now I’ll just link to its documentation site, which might be the best I’ve ever seen or used.

+ +

Templater

+ +

Originally written by SilentVoid13, the Templater plugin allows for things beyond what Obsidian’s built-in Templates plugin provide. I think maintenance of it has been taken over by Zach Young, aka Zachatoo, who provides excellent guidance to it in the Obsidian Discord.

+ +

Two of the most powerful things I’ve used it for are moving notes to specific folders as you create the notes (very useful for keeping project notes organized!) and creating “partials” or “includes.” By this I mean that I have a general daily note template in my digital bullet journal, and then use a set of if/then statements to include a different set of default tasks/schedule based on which day of the week it happens to be.

+ +

This is another plugin about which I might eventually write a whole separate note, since its features and behaviors are far from self-explanatory to non-coders like me.

+ +
+ + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ +
+ + + + + + + + + + +
+ Created: +
+ + +
+ Updated: +
+ +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Note-taking/Obsidian/obsidian-tasks-plugin-patterns.html b/notes/Note-taking/Obsidian/obsidian-tasks-plugin-patterns.html new file mode 100644 index 000000000..8b3358c38 --- /dev/null +++ b/notes/Note-taking/Obsidian/obsidian-tasks-plugin-patterns.html @@ -0,0 +1,721 @@ + + + + + + +Obsidian Tasks Plugin — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + Note taking / + + + + Obsidian / + + + + obsidian tasks plugin patterns + + +
+ + +
Created: +
+ + +
Updated: +
+ + +

Note status: :herb:

+ + +
+ +

Assumed audience People at least passably familiar with Obsidian. See my other notes on Obsidian for more context.

+ +

What is the Tasks plugin?

+ +

Originally written by Martin Schenck and now expertly maintained by Clare Macrae, the Tasks plugin is the thing that ultimately convinced me to switch from Dendron to Obsidian for my default note-taking environment. It’s obviously the highest in my shortlist of obsidian-plugins.

+ +

It lets you track and display tasks using a variety of queries and filters, which then get dynamically displayed in other views of your notes. If the longevity of Markdown appeals to you, but you’d also like to augment that with other features, Tasks is a great place to start.

+ +

For example, if the “source code” (plain Markdown text) of a note contains the following instructions:

+
```tasks 
+not done 
+starts before tomorrow
+(tags do not include #waiting)
+group by happens
+```
+
+ +

Then the “reading view” or “live preview” of the note can display a list of tasks from any of your Obsidian notes, nicely grouped together by day, and with optional links back to the original note that contains the task.

+ +

Here is an example with five different tasks, grouped into headings under three different days:
+five example tasks, each about writing a set of clever task examples

+ +

Patterns I Use Most

+ +

Task’s own documentation site might be the best I’ve ever seen or used. I highly recommend you consult it.

+ +

Here I’ll share a few of the patterns (i.e. queries and filters) I use most frequently, and then show how I connect them all at the end.

+ +

Global Query, or Separating Tasks from Regular Checkboxes

+ +

Many Markdown apps will turn - [ ] into a checkbox, and Obsidian follows suit here. By default, the Tasks plugin will treat every checkbox as a task, automatically querying every line that begins with a checklist.

+ +

This is a great default, especially if you’re new to using Markdown. I have notes going back about a decade at this point, through, and I’ve often used that checkbox pattern as a welcome reminder for components of my daily workplace routines. (Yes, I do indeed have ADHD, why do you ask?)

+ +

Since I don’t want to needlessly ask Tasks to query long out-of-date things that were just prompts, not things I truly needed to track, I immediately began using what Tasks calls a “Global Query” to separate regular - [ ] things from things that catch the attention of the Tasks plugin.

+ +

To be clear: Clare, who maintains the Tasks plugin, has said that the plugin is performant enough that these global queries aren’t really necessary—and I have no reason to doubt her! I just had already adopted this approach before seeing that message from her, and haven’t yet found a compelling reason to stop. So you likely won’t need to use this pattern, but I’m explaining why you might see that in my examples below.

+ +

I use #tt as my global query, since it’s simple to type and I can’t imagine every using that for a regular tag. Again, this might be entirely superfluous for most people, and even for me! I’m just explaining what I do, as of when I write this note on 2023-11-18.

+ +

Basic Query within a Single File

+ +

A basic query looks something like this:

+ +
```tasks
+not done 
+filename includes {{query.file.filename}}
+group by happens
+```
+
+ +

Line-by-line, this will:

+
    +
  1. start the Tasks query (with the ```tasks command).
  2. +
  3. return only tasks that aren’t already done (with the not done filter).
  4. +
  5. return only tasks written are on this same file (with the filename includes {{query.file.filename}} filter).
  6. +
  7. sort these according to the earliest of start date, scheduled date, or due date (with the group by happens filter).
  8. +
  9. ends the Tasks query (with the ``` three backticks).
  10. +
+ +

That {{query.file.filename}} query was recently added and has already proven extremely handy. I include the above query in a template for all my project files, and I used to have to remember to make sure that the file name was listed verbatim in the query. Now, however, this line of code always knows to just look on the same page where it’s included. A definitely time-saver!

+ +

Basic Query Across Files

+ +

In addition to the various project files, I keep a sort of “digital bullet journal” of daily notes in Obsidian. My daily template includes various Tasks queries, set up to search across other files.

+ +

A relatively basic query looks something like this:

+ +
```tasks
+not done
+starts before tomorrow
+filename includes life.writing.acwrimo.2023.md
+(tags include #td/writing)
+```
+
+ +

Line-by-line, this will:

+
    +
  1. start the Tasks query (with the ```tasks command).
  2. +
  3. return only tasks that aren’t already done (with the not done filter).
  4. +
  5. return only tasks that aren’t far into the future (with the starts before tomorrow filter).
  6. +
  7. returns only tasks from a specific other file (with the filename includes life.writing.acwrimo.2023.md filter).
  8. +
  9. returns only tasks with a specific tag (with the (tags include #td/writing) filter).
  10. +
  11. ends the Tasks query (with the ``` three backticks).
  12. +
+ +

Usually I don’t use a filename query (like on line 4 above), and instead just have a query return all tasks with a certain tag (like on line 5). I figured I’d share an example that does both, though, just to show you how easily you can adjust the scope of what you see using the different filters.

+ +

Without that filename query, the above query would get any task that includes #td/writing. In my case, that would include ideas I’ve jotted down for my blog or digital garden, ideas for academic writing, ideas for things I’ve writing at work, etc. Since November is Academic Writing Month (…and here’s my post about AcWriMo2023 ), I wanted a more prominent and specific query reminding me to do this throughout the month.

+ +

Daily Note Task Queries

+ +

The ability to query and filter by tags allows you to display tasks in handy ways. I use multiple queries in my daily note templates to automatically display tasks in groups that work for me.

+ +

Here’s the main query I use:

+ +
```tasks 
+not done 
+starts before tomorrow
+(tags do not include #td/work)
+(tags do not include #td/writing)
+group by tags
+group by happens
+```
+
+ +

Line-by-line, this will:

+
    +
  1. start the Tasks query (with the ```tasks command).
  2. +
  3. return only tasks that start before tomorrow, not ones further into the future (with the starts before tomorrow filter).
  4. +
  5. return only tasks that don’t have the #td/work tag (with the (tags do not include #td/work) filter).
  6. +
  7. return only tasks that don’t have the #td/writing tag (with the (tags do not include #td/writing) filter).
  8. +
  9. group the tasks by tag (with the (group by tags) filter).
  10. +
  11. sort these according to the earliest of start date, scheduled date, or due date (with the group by happens filter).
  12. +
  13. ends the Tasks query (with the ``` three backticks).
  14. +
+ +

I put the above after two similar queries, each of which displays only tasks with #td/work or #td/writing tags.

+ +

This helps me context switch more easily throughout the day. I can ignore or even fold the entire heading that has my work-related tasks, jump to my writing-related tasks after my work is done, and then look at all the other tasks I in one long query. These include things like any classes I’m taking, any blogging or website maintenance I’ve tagged outside of the writing tag, paying recurring bills, etc.

+ +

Still to Write: Adding Time Elements to Tasks

+ +

I’m done bashing out the first version of this note, and I haven’t yet mentioned how to actually indicate date-related elements in Tasks. I’ll probably add more about this later. For now, here’s a link to the Tasks’ own Dates documentation page.

+ +

Coda

+ +

Hopefully this helps you better understand what the Tasks plugin can do, and whether you might want to use it yourself. It’s the most flexible solution I’ve found, and I’ve used quite a few options. If you’re not a Markdown fan like myself, Tasks might not be for you! But if you are—and I assume you probably are, if you’re still reading this—it’s well worth an hour of experimentation to see if it’ll suit your ways of working.

+ +

Good luck finding what works for you, whether or not this is it!

+ +
+ + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ +
+ + + + + + + + + + +
+ Created: +
+ + +
+ Updated: +
+ +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Note-taking/index.html b/notes/Note-taking/index.html new file mode 100644 index 000000000..e496e2386 --- /dev/null +++ b/notes/Note-taking/index.html @@ -0,0 +1,597 @@ + + + + + + +Note taking — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+
+ + + + + +
+ + + + + + + + + +
+ +
+

Note taking +

+ + + +
+ + +
+ + + + +
+ +
+
a wonky wiki, a digital garden
+
+
+ +
+ + home / + + + notes / + + + + Note taking / + + + + index + + +
+ +

All Note taking folders

+ + + + + + + + + + +
+ +
+ Dendron +
+
+ Obsidian +
+ +
+ + + + + +

All Note taking items

+ + + + + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + + +
+ +
+ + + + + + +
+ Created: +
+ + +
+ + + +
+ + +
+ + + +
+
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Pedagogy/index.html b/notes/Pedagogy/index.html new file mode 100644 index 000000000..747497de7 --- /dev/null +++ b/notes/Pedagogy/index.html @@ -0,0 +1,502 @@ + + + + + + +Pedagogy — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+
+ + + + + +
+ + + + + + + + + +
+ +
+

Pedagogy +

+ + + +
+ + +
+ + + + +
+ +
+
a wonky wiki, a digital garden
+
+
+ +
+ + home / + + + notes / + + + + Pedagogy / + + + + index + + +
+ + + + + +

All Pedagogy items

+ + +

There's nothing here yet!

+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + + +
+ +
+ + + + + + +
+ Created: +
+ + +
+ + + +
+ + +
+ + + +
+
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Reading/Articles/index.html b/notes/Reading/Articles/index.html new file mode 100644 index 000000000..40d422005 --- /dev/null +++ b/notes/Reading/Articles/index.html @@ -0,0 +1,529 @@ + + + + + + +Articles — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+
+ + + + + +
+ + + + + + + + + +
+ +
+

Articles +

+ + + +
+ + +
+ + + + +
+ +
+
a wonky wiki, a digital garden
+
+
+ +
+ + home / + + + notes / + + + + Reading / + + + + Articles / + + + + index + + +
+ + + + +

All my notes on articles I've read

+ + + + + +

All my reading notes on articles by year

+ + + + + + +

There's nothing here yet!

+ + + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + + +
+ +
+ + + + + + +
+ Created: +
+ + +
+ + + +
+ + +
+ + + +
+
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Reading/Articles/riggs-and-linder-actively-engaging-students.html b/notes/Reading/Articles/riggs-and-linder-actively-engaging-students.html new file mode 100644 index 000000000..88d24b63d --- /dev/null +++ b/notes/Reading/Articles/riggs-and-linder-actively-engaging-students.html @@ -0,0 +1,591 @@ + + + + + + +Actively Engaging Students in Asynchronous Online Classes. — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + Reading / + + + + Articles / + + + + riggs and linder actively engaging students + + +
+ + +
Created: +
+ + +
Updated: +
+ + +

Note status: :herb:

+ + +
+ +

From the paper’s own abstract:

+
+

This paper suggests a three-pronged approach for conceptualizing active learning in the online asynchronous class: the creation of an architecture of engagement in the online classroom, the use of web-based tools in addition to the learning management system, and a re-imagining of discussion boards as interactive spaces.

+
+ +
+ + +

Details

+

:page_facing_up: "Actively Engaging Students in Asynchronous Online Classes." +
+ Link: IDEA Center
+ By: Shannon A. Riggs and Kathryn E. Linder
+ Started: 2023-01-19 +
Finished: 2023-01-20
+ Amount read: 10 of 10 pages

+ 10 pages + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ +
+ + + + + + + + + + +
+ Created: +
+ + +
+ Updated: +
+ +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Reading/Books/hall-policing-the-crisis.html b/notes/Reading/Books/hall-policing-the-crisis.html new file mode 100644 index 000000000..947676042 --- /dev/null +++ b/notes/Reading/Books/hall-policing-the-crisis.html @@ -0,0 +1,588 @@ + + + + + + +Policing the Crisis: Mugging, the State, and Law and Order — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + Reading / + + + + Books / + + + + hall policing the crisis + + +
+ + +
Created: +
+ + +
Updated: +
+ + +

Note status: :herb:

+ + +
+ +

Hall and cowriters provide a classic analysis of the rhetoric of a moral panic.

+ +
+ + +

Details

+

+ :book: Policing the Crisis: Mugging, the State, and Law and Order
+ Link: OpenLibrary
+ By: Stuart Hall, Chas Critcher, Tony Jefferson, John Clarke, and Brian Roberts
+ Started: 2022-10-02 +
+ Amount read: 32 of 451 pages

+ 32 pages + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ +
+ + + + + + + + + + +
+ Created: +
+ + +
+ Updated: +
+ +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Reading/Books/index.html b/notes/Reading/Books/index.html new file mode 100644 index 000000000..ea4c5dba5 --- /dev/null +++ b/notes/Reading/Books/index.html @@ -0,0 +1,554 @@ + + + + + + +Books — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+
+ + + + + +
+ + + + + + + + + +
+ +
+

Books +

+ + + +
+ + +
+ + + + +
+ +
+
a wonky wiki, a digital garden
+
+
+ +
+ + home / + + + notes / + + + + Reading / + + + + Books / + + + + index + + +
+ + + + + +

All my notes on books I've read

+ + + + + +

All my reading notes on books by year

+ + + +

There's nothing here yet!

+ +
+
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + + + + +
+ + + + + + +
+ Created: +
+ + +
+ + + +
+
+ + + + + + +
+ + + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Reading/Books/lee-overwhelmed.html b/notes/Reading/Books/lee-overwhelmed.html new file mode 100644 index 000000000..2ae3a67ae --- /dev/null +++ b/notes/Reading/Books/lee-overwhelmed.html @@ -0,0 +1,579 @@ + + + + + + +Overwhelmed: Literature, Aesthetics, and the Nineteenth-Century Information Revolution — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + Reading / + + + + Books / + + + + lee overwhelmed + + +
+ + +
Created: +
+ + + +

Note status: :herb:

+ + +
+ +

Lee explores the history of how various cultural formations around literature and information grew through the 19th Century Information Revolution.

+ +
+ + +

Details

+

+ :book: Overwhelmed: Literature, Aesthetics, and the Nineteenth-Century Information Revolution
+ Link: OpenLibrary
+ By: Maurice S. Lee
+ Started: 2023-11-12 +
+ Amount read: 9 of 277 pages

+ 9 pages + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ + + + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Reading/Books/purdon-modernist-informatics.html b/notes/Reading/Books/purdon-modernist-informatics.html new file mode 100644 index 000000000..0542250a7 --- /dev/null +++ b/notes/Reading/Books/purdon-modernist-informatics.html @@ -0,0 +1,588 @@ + + + + + + +Modernist Informatics: Literature, Information, and the State — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + Reading / + + + + Books / + + + + purdon modernist informatics + + +
+ + +
Created: +
+ + +
Updated: +
+ + +

Note status: :herb:

+ + +
+ +

Purdon examines modernist fiction to trace how writers experienced information culture as a disturbing interruption and governmental intrusion.

+ +
+ + +

Details

+

+ :book: Modernist Informatics: Literature, Information, and the State
+ Link: OpenLibrary
+ By: James Purdon
+ Started: 2022-11-02 +
Finished: 2023-11-02
+ Amount read: 224 of 224 pages

+ 224 pages + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ +
+ + + + + + + + + + +
+ Created: +
+ + +
+ Updated: +
+ +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Reading/Books/wark-capital-is-dead.html b/notes/Reading/Books/wark-capital-is-dead.html new file mode 100644 index 000000000..0ef48255e --- /dev/null +++ b/notes/Reading/Books/wark-capital-is-dead.html @@ -0,0 +1,588 @@ + + + + + + +Capital is Dead. Is This Something Worse? — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + Reading / + + + + Books / + + + + wark capital is dead + + +
+ + +
Created: +
+ + +
Updated: +
+ + +

Note status: :herb:

+ + +
+ +

Wark asks us to think about information less like Marxists and more like Marx.

+ +
+ + +

Details

+

+ :book: Capital is Dead. Is This Something Worse?
+ Link: OpenLibrary
+ By: McKenzie Wark
+ Started: 2023-01-02 +
+ Amount read: 158 of 240 pages

+ 158 pages + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ +
+ + + + + + + + + + +
+ Created: +
+ + +
+ Updated: +
+ +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Reading/index.html b/notes/Reading/index.html new file mode 100644 index 000000000..7d695a358 --- /dev/null +++ b/notes/Reading/index.html @@ -0,0 +1,567 @@ + + + + + + +Reading — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+
+ + + + + +
+ + + + + + + + + +
+ +
+

Reading +

+ + + +
+ + +
+ + + + +
+ +
+
a wonky wiki, a digital garden
+
+
+ +
+ + home / + + + notes / + + + + Reading / + + + + index + + +
+ +

All Reading folders

+ + + + + + + + +
+
+ Articles +
+
+ Books +
+
+ +

All notes on what I've read

+ + + + + +

All my reading notes by year

+ + +

There's nothing here yet!

+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + + +
+ +
+ + + + + + +
+ Created: +
+ + +
+ + + +
+ + +
+ + + +
+
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Snippets/index.html b/notes/Snippets/index.html new file mode 100644 index 000000000..d82d3ba06 --- /dev/null +++ b/notes/Snippets/index.html @@ -0,0 +1,512 @@ + + + + + + +Snippets — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+
+ + + + + +
+ + + + + + + + + +
+ +
+

Snippets +

+ + + +
+ + +
+ + + + +
+ +
+
a wonky wiki, a digital garden
+
+
+ +
+ + home / + + + notes / + + + + Snippets / + + + + index + + +
+ + + + + +

All Snippets items

+ + + + + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + + +
+ +
+ + + + + + +
+ Created: +
+ + +
+ + + +
+ + +
+ + + +
+
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Snippets/information-informatics.html b/notes/Snippets/information-informatics.html new file mode 100644 index 000000000..b885f8451 --- /dev/null +++ b/notes/Snippets/information-informatics.html @@ -0,0 +1,601 @@ + + + + + + +Information Informatics — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + Snippets / + + + + information informatics + + +
+ + +
Created: +
+ + +
Updated: +
+ + +

Note status: :seedling:

+ + +
+ +

Here are some insightful snippets about “information” & “informatics” that I’ve found.
+2020

+

Purdon, Modernist Informatics +

+ +

Modernist Informatics: Literature, Information, and the State

+ +
+

In the company kept by the word—public service and business, agency and control—we can begin to discern the outline of a modern understanding of information as a form of mediation which structures relations between individuals, corporations, and state bureaucracies. (5)

+
+ +
+

Informatics can be regarded as the infrastructure of information, but it need not be limited to digital computing machines, or indeed to machines alone. The most recent edition of the International Encyclopaedia of Information and Library Science, for instance, allows that since “computers, individuals , and organizations all process information, informatics has computational, {»5/6«} cognitive, and social aspects.” Informatics, that is to say, deals with the representation, processing, and communication of information within and between systems of several kinds: not only “computer communications and networking” but “paper, analogue and digital records,” “organizational processes,” and even “human reasoning.” (5-6)

+
+ +
+

Modernist Informatics explores the premise that informatics begins not with digitization but rather with the development of new information controls in nineteenth- and early twentieth-century government systems. Informatics might then be understood as the government of information, allowing that phrase its full measure of ambiguity in order to call to mind the way information has emerged as both the basis of modern political power and one of its primary objects of attention and control. (6)

+
+ +
+

Modernist Informatics charts the structures of information in modernist culture by attending to moments at which those structures emerge into view, but it also insists that “the politics of information,” far from constituting a new field for the exercise of forms of official power later to be represented in cultural artifacts, was one of the principal ways in which both the state and literary culture came to define themselves in the new century. (8)

+
+ +
+

As Daniel R. Headrick has pointed out, “information” has come to designate a category so vague as to be critically useless: he therefore turns his attention to “a more manageable concept, the study of information systems.” (9)

+
+ +

The above quotes come from Purdon’s intro and do a great job of revealing the context within which our current notions of “information” and “informatics” developed and solidified. As he traces “information” through a number of different thinkers, he shows that our current conception of information has long been tied to political projects.

+ +
+ + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ +
+ + + + + + + + + + +
+ Created: +
+ + +
+ Updated: +
+ +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Technology/Jekyll/index.html b/notes/Technology/Jekyll/index.html new file mode 100644 index 000000000..47a4a583c --- /dev/null +++ b/notes/Technology/Jekyll/index.html @@ -0,0 +1,516 @@ + + + + + + +Jekyll — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+
+ + + + + +
+ + + + + + + + + +
+ +
+

Jekyll +

+ + + +
+ + +
+ + + + +
+ +
+
a wonky wiki, a digital garden
+
+
+ +
+ + home / + + + notes / + + + + Technology / + + + + Jekyll / + + + + index + + +
+ + + + + +

All Jekyll items

+ + + + + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + + +
+ +
+ + + + + + +
+ Created: +
+ + +
+ + + +
+ + +
+ + + +
+
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Technology/Jekyll/jekyll-guides.html b/notes/Technology/Jekyll/jekyll-guides.html new file mode 100644 index 000000000..70fa558ba --- /dev/null +++ b/notes/Technology/Jekyll/jekyll-guides.html @@ -0,0 +1,578 @@ + + + + + + +Jekyll Guides — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + Technology / + + + + Jekyll / + + + + jekyll guides + + +
+ + +
Created: +
+ + + +

Note status: :seedling:

+ + +
+ +

I really enjoy using Jekyll, enough that I’d recommend it to anyone who is both looking to make their own site and has the time or inclination to do more “behind the scenes” than necessary for site made with WordPress or Squarespace.

+ +

Jekyll’s own documentation is one of the most helpful sets of official docs I’ve ever relied upon. There’s also a larger group of Jekyll users who often make guides. This note will corral some of the ones I refer to most often, with short annotations.

+ + + +
    +
  • +URLs and links in Jekyll: This guide by Michael Rose, who made and maintains a few of the most popular Jekyll themes, helps explain some of the filters you can use when linking, or the often-confusing parts of site.url and site.baseurl. Since my site is hosted on GitHub pages but has a different URL, I often have to rely on the different tags explained here, rather than hard-coding a specific URL in the link.
  • +
+ +
+ + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ + + + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Technology/Social-Media/index.html b/notes/Technology/Social-Media/index.html new file mode 100644 index 000000000..ea52be885 --- /dev/null +++ b/notes/Technology/Social-Media/index.html @@ -0,0 +1,524 @@ + + + + + + +Social Media — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+
+ + + + + +
+ + + + + + + + + +
+ +
+

Social Media +

+ + + +
+ + +
+ + + + +
+ +
+
a wonky wiki, a digital garden
+
+
+ +
+ + home / + + + notes / + + + + Technology / + + + + Social Media / + + + + index + + +
+ + + + + +

All Social Media items

+ + + + + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + + +
+ +
+ + + + + + +
+ Created: +
+ + +
+ + + +
+ + +
+ + + +
+
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Technology/Social-Media/mastodon-apps.html b/notes/Technology/Social-Media/mastodon-apps.html new file mode 100644 index 000000000..53fc1461d --- /dev/null +++ b/notes/Technology/Social-Media/mastodon-apps.html @@ -0,0 +1,603 @@ + + + + + + +Mastodon Apps — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + Technology / + + + + Social Media / + + + + mastodon apps + + +
+ + +
Created: +
+ + +
Updated: +
+ + +

Note status: :seedling:

+ + +
+ +

I’ve been using Mastodon for a while. Apparently at least since April of 2017‽?!

+ + + + +

I tend to use Mastodon on my phone at least as much as I do through a browser. At various times I’ve used Metatext, Mast, Amaroq, and a tab of Safari pinned to appear as its own “app.”

+ +

Metatext

+ +

As of 2022-11-19, my current preference is for using Metatext.

+ +

Here are the things I really like about it:

+
    +
  • It handles multiple accounts well. (Although the interface could be clearer; one has to click on your own profile image in order to bring up the menu where you can click on “Accounts” to switch between your accounts.)
  • +
  • It has a dark theme, which is important for insomniac scrolling.
  • +
  • It easily displays alt text for images. (Press on an image and it will focus in a sort of “lightbox” modal that hides the rest of the post, exposing the alt text at the bottom of the screen somewhat like a caption.)
  • +
+ +

Other Mastodonkulous Notes

+ +

Mastodon settings

+ +
+ + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ +
+ + + + + + + + + + +
+ Created: +
+ + +
+ Updated: +
+ +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Technology/Social-Media/mastodon-settings.html b/notes/Technology/Social-Media/mastodon-settings.html new file mode 100644 index 000000000..d20741b69 --- /dev/null +++ b/notes/Technology/Social-Media/mastodon-settings.html @@ -0,0 +1,703 @@ + + + + + + +Mastodon Settings — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + Technology / + + + + Social Media / + + + + mastodon settings + + +
+ + +
Created: +
+ + +
Updated: +
+ + +

Note status: :seedling:

+ + +
+ +
+ +

This isn’t trying to be comprehensive, or even an overview.

+ +

This is just me writing up some notes, as if I were explaining the settings to someone in my family. I’m not checking every setting to see if my recommendation varies from the default. If I remember, I’ll probably refine this after a few days. (Today is 2022-11-20.)

+ +
+ +

Mastodon manages to be simultaneously very customizable and deeply confusing. This isn’t helped by some of the default settings funneling you toward rapidly-updating streams, and other choices that don’t handle scale nicely.

+ +

Here’s a quick rundown of some settings you might consider, especially as you’re getting used to things.

+ +

First of all, click on the little “gear,” which is probably labelled “Preferences” if you hover over it. This brings us to the “Appearance” part of the settings.

+ +

Appearance

+ +

Enable Advanced Web Interface

+ +

If you ever used Tweetdeck, you might be familiar with Twitter’s column view rather than a single view. If I recall, back when I started using Mastodon in 2017, this “Advanced” web interface was the standard view. Maybe Eugen changed the default to make Mastodon seem less weird… but now that there are so many people on so many servers, you’ll probably want to start following hashtags or people via lists.

+ +

If you agree that columns are good, this is the setting you’ll want.

+ +

If you don’t agree (yet)… well, just remember that this setting exists, okay?

+ +

Slow Mode

+ +

This’s label explains it succinctly: “Hide timeline updates behind a click instead of automatically scrolling the feed.”

+ +

Certain timelines—the federated one for most instances, and even the local one for larger servers—will often rush by, updating too quickly to read any particular message.

+ +

Hide Media Marked as Sensitive

+ +

Mastodon’s long had some NSFW corners. Your mileage, workplaces, and levels of embarassment might vary, but I’d recommend making sure that the “Hide media marked as sensitive” is checked and stays checked.

+ +

Other Options

+ +

I don’t check this one, but there is an “Always expand posts marked with content warnings” setting. There’s a long-running Discourse about content warnings—which you might instead coceived of as content wrappers or consent widgets—but it’s a practice in many servers to treat them as basically expected on any public post, regardless of whether you think the content merits a “warning.”

+ +

Once you have a very busy feed, you might appreciate a CW-heavy approach, since it makes the CW act like a subject line and “read more” cut on blogs or other social media. But if this strikes you as unnecessary, you can make every post expand by clicking on this setting. That’s a large part of the beauty of Mastodon—it hands you more control over what you see, rather than handing it over to some sort of for-profit surveillance capitalist outfit.

+ +

Save Changes

+ +

Yeah, you’ll have to do that. It doesn’t automatically keep your settings like some other social media sites.

+ +

Other (Under Preferences)

+ +

Opt-out of search engine indexing

+ +

You do you, but I think this is a prudent choice as you’re getting used to the ramifications of the different privacy options.

+ +

Posting Defaults

+ +

Unlisted is what I’d recommend here.

+ +

Mastodon allows for three levels of posting (in addition to direct messages, which aren’t exactly posts). From most to least permissive, these are Public, Unlisted, and Followers-Only. Public posts can be seen by anyone, and they allow you to use hashtags. Unlisted ones can be seen by everyone, but they’re not on public timelines. People will either need to be following you (and viewing their home timelines) or go to your own profile in order to see these. Followers-only are visible only to the accounts you’ve let follow you.

+ +

If you’re going to write a thread, it’s a very kind practice to make the first post public, then the subsequent ones unlisted. This makes the first show up in the shared timeline, and then all the rest can be viewed but won’t hog more scrolling space. Changing each post’s setting to “Unlisted” is precisely the sort of thing I forget when I’m typing, so I’ve set my default to “Unlisted,” and then I change that only when I intentionally want to raise my pixellated voice a bit louder.

+ +

Public Timelines

+ +

You can filter languages. So many languages! If you’re able to read multiple languages, or are trying to learn, it’s a really cool feature. I leave this unchecked, since I can kinda-sorta muddle through most Romance languages, and I appreciate the reminder that English isn’t the world’s default.

+ +

If you do want to use this filter, I’d recommend that you look closely at different languages. For instance, if you can read Spanish (Español) very comfortably, you might also consider leaving aragonés, Català, and perhaps some other related languages checked.

+ +

Filters

+ +

You can filter tons of things in Mastodon, in refined ways. If you don’t want to have to read another “Meta” post (a description often used for a post about Mastodon or the Fediverse), you can whisk them all out of your timelines. You can even set which timeline!

+ +

Click on “Add new filter” and start doing Future You some favors!

+ +

Profile

+ +

Appearance

+ +

Okay, now that you’ve set things up to make reading more comfortable, you can start reading the digital room.

+ +

Require follow requests

+ +

This is what I do. Mastodon’s wild growth means that people are often making multiple accounts… which also means it’s a great time to impersonate people. So if you don’t want to have just any old person start reading you when you’re unguarded, you might want to click this.

+ +

I’d click it now… you can always change this later if you start feeling lonely!

+ +

Profile Metadata & Verification

+ +

Since people can have as many Mastodon accounts as they can create, verification is prudent. If you have a website or profile elsewhere, you can add a special code to make Mastodon show this link in green.

+ +

Please do this if you can!

+ +

As an example, on my Humanities Commons profile, I copied and pasted the special html link from Mastodon into my About section. The important bit here is the rel="me" attribute on the html link.

+ +

Many of the more pleasant “visual” interfaces, such as WordPress or ORCID, currently seem to automatically, silently remove this rel="me" from links when you paste them in. So I’d recommend that you use the “code” or “html” view to add the link yourself. If you copy the “Verification” code directly from Mastodon, the only thing you might want to reword is where it says Mastodon, right before the closing </a> tag.

+ +

For instance, if you are on multiple instances, you might want to differentiate between them. If what you copy and paste starts out as <a rel="me" href="https://example.social/@nerdcore">Mastodon</a>, you might instead want to change the last few characters to instead read Example.social</a>. Repeat that for each instance you want to verify.

+ +

Other Mastodonkulous Notes

+ +

Mastodon apps

+ +
+ + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ +
+ + + + + + + + + + +
+ Created: +
+ + +
+ Updated: +
+ +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Technology/VS-Code/daybreak-theme.html b/notes/Technology/VS-Code/daybreak-theme.html new file mode 100644 index 000000000..dc97d514d --- /dev/null +++ b/notes/Technology/VS-Code/daybreak-theme.html @@ -0,0 +1,682 @@ + + + + + + +Daybreak Theme — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + Technology / + + + + VS Code / + + + + daybreak theme + + +
+ + +
Created: +
+ + +
Updated: +
+ + +

Note status: :herb:

+ + +
+ +

Horizon, then Daybreak

+ +

I’m a big fan of dark themes. I’ve been using variants of Horizon for quite a while now in VS Code (as you can read about in vs code note), since I like the overall warmth of the theme’s color palette.

+ +

Unfortunately, the person who initially designed Horizon doesn’t seem to be actively maintaining it. Their original version is no longer findable in the VS Code extensions respository. Thankfully, the Daybreak variant fills this void nicely!

+ +

Color Contrast

+ +

Activity Bar Contrast

+ +

The one thing I’m not a fan of about Daybreak is that the activity bar icons are extremely low-contrast. Especially if you lower the brightness of your monitor, you almost need to remember the order of the icons in order to know where to put your cursor.

+ +
+ + + + original with low-contrast icons + + + + + + my current preference, which is easier to perceive + + + + + + colors with transparency + + + + +
Here are three versions for the sidebar colors. My current preference is the middle one, with the highest contrast. +
+ +
+ +

Here are the original colors:

+ +
+ original with low-contrast icons
+ +

VS Code lets you add customizations, so this isn’t difficult to override.

+ +

Here are the colors I’m using as of 2022-04-21:

+ +
+ my current preference, which is easier to perceive
+ +

This is what I’ve added to my settings.json file to achieve this:

+ +
    "workbench.colorCustomizations": {
+        "activityBar.inactiveForeground": "#6C6F93"
+        }
+
+ +

The snippet above applies the dark purple/gray (which—apologies for the low contrast on this page—looks like this) from the original Horizon theme’s Dark UI palette just to the inactive icons. This makes the colors much easier to see on a dimmed monitor.

+ +

Here’s a version that lands somewhere in between, which you might prefer if your monitor is often at full brightness.

+ +
+ colors with transparency
+ +

This is the code to achieve these colors:

+ +
    "workbench.colorCustomizations": {
+        "activityBar.inactiveForeground": "#6C6F9395"
+        }
+
+ +

The original value for the purple/grey is #6C6F93 — and in the above snippet, the last two digits in the code reduce the opacity from 100% to 58.5%. This is more than enough to help “situate” the color in the bar, at least to my eyes. It’s a good balance of increasing the contrast while still visually prioritizing the active icons.

+ +

But wait—why does 95 equal 58.5%? I’d forgotten that these values are in hex notation—and therefore, anything in the 90% range would need to start with F.

+ +

Scrollbar Contrast

+ +

Update on 2023-03-01:

+ +

I noticed earlier today that in a very long file, I could barely make out the scrollbar.

+ +

So I’ve added the below lines, to quickly make the scrollbar the same color as the inactive icons in the Activity Bar, and to make it slightly darker when I’ve hovered over it.

+ +
    "workbench.colorCustomizations": {
+        "scrollbarSlider.background": "#6C6F93",
+        "scrollbarSlider.hoverBackground": "#6C6F9395"
+        }
+
+ +

If I were really making a “proper” theme, I’d probably take the time to make the scrollbar a little lower contrast, as it’s much more more obvious in this shorter file. But the overall point of this note is precisely this opportunity for customization!

+ +

Other Themes

+ +

Even if you don’t love this particular theme, hopefully this note helps you trick out VS Code however suits you!

+ +
+ + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ +
+ + + + + + + + + + +
+ Created: +
+ + +
+ Updated: +
+ +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Technology/VS-Code/index.html b/notes/Technology/VS-Code/index.html new file mode 100644 index 000000000..1215ff61a --- /dev/null +++ b/notes/Technology/VS-Code/index.html @@ -0,0 +1,540 @@ + + + + + + +VS Code — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+
+ + + + + +
+ + + + + + + + + +
+ +
+

VS Code +

+ + + +
+ + +
+ + + + +
+ +
+
a wonky wiki, a digital garden
+
+
+ +
+ + home / + + + notes / + + + + Technology / + + + + VS Code / + + + + index + + +
+ + + + + +

All VS Code items

+ + + + + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + + +
+ +
+ + + + + + +
+ Created: +
+ + +
+ + + +
+ + +
+ + + +
+
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Technology/VS-Code/vs-code-snippets.html b/notes/Technology/VS-Code/vs-code-snippets.html new file mode 100644 index 000000000..d4e04bfac --- /dev/null +++ b/notes/Technology/VS-Code/vs-code-snippets.html @@ -0,0 +1,863 @@ + + + + + + +VS Code Snippets — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + Technology / + + + + VS Code / + + + + vs code snippets + + +
+ + +
Created: +
+ + +
Updated: +
+ + +

Note status: :herb:

+ + +
+ +

This is one of my longest notes. Please don’t forget that the Table of Contents can help you jump to a particular section!

+ +

I’m a fan of keeping a Bullet Journal in a text editor, as I’ve written about in task-tracking-in-dendron.

+ +

A Digital Bullet Journal might not seem like a very straightforward approach, but here’s a non-exhaustive list of things I like about it:

+ +
    +
  • it’s more customizable than most dedicated Bullet Journal or GTD programs
  • +
  • the files involved (text or Markdown) are about as small and durable as computer files can be
  • +
  • it’s relatively distraction-free
  • +
+ +

Context and Syntax

+ +

Snippets are a substantial part of this customization. I use quite a few snippets in VS Code, both for bullet journal / daily log sort of things and HTML / CSS patterns. They allow both for quickly including repetitive patterns and for automatically including things like dates or times. There are more advanced possibilities, too, but I haven’t really explored those yet.

+ +

Snippet Considerations

+ +

Probably the most difficult thing about using snippets isn’t realizing where you can use them or even setting them up in your text editors or system-level keyboard settings; it’s figuring out which prefixes and shortcodes to use as the expansion pattern. For the last few years, I’ve settled on usually using a semicolon followed immediately by a memorable abbreviation. I can’t think of a time in natural language when I’d write a semicolon without a space after it, so it’s served well as a pattern for invoking these kind of snippets. The ; also is availably right under my pinky on a physical keyboard, and usually is on the primary or occasionally secondary level of a mobile device’s digital keyboard as well.

+ +

I still occasionally have the muscle memory of using a strudel (a @, which you might call an “at sign” if you’re not of the pastry persuasion), so I’ve set up a number of these snippets to allow multiple invocation patterns. If you’re going to use wizardry, do so inclusively!

+ +

VS Code Snippet Syntax

+ +

You can store snippets in VS Code in a number of different places. For my purposes, it’s so far been sufficient to use a global snippets file and add the few languages in scope. That way I don’t have to remember to add each pattern for each new language I start using. I can just keep a single file and occasionally add any new language to the snippet’s scope as desired.

+ +

Here’s my basic pattern for a snippet, with comments added after //:

+
"snippet name": { // I usually use the output, i.e. `#;done`
+    "prefix": ["@dd", ";dd"], // the string(s) that will invoke the snippet
+    "scope": "markdown,yaml", // the language(s) where the snippet will work, if you don't want it to work everywhere
+    "description": "Add #;done", // just a note to you or others sharing your files
+    "body": [ // the snippet pattern itself, with any new line on another new line
+        "#;done",
+    ],
+}
+
+
+ +

Bullet Journal / Task Management Snippets

+ +

I keep a Digital Bullet Journal mostly based around weekly notes. I also use Dendron’s tags, which start with # characters. As far as I can tell, most other Markdown-based tools I’ve tried out (like Zettlr or Obsidian) have similarly converged on using @ for tagging people and # for tagging concepts.

+ +

Here’s a few of the snippets I’ve found very handy for this kind of DigiBuJo / text-file-based task management system.

+ +

#;done

+ +

I’ve found that adding a tag indicating that I’m done with a particular day or task makes it much easier to scan files and reacquaint myself to what info is now just a record of the past and what info is still “live” or “in play.” It helps when skimming using an outline view, when folding headings, or even just when opening a note and realizing that there’s a #;done annotation on the first heading, indicating that the entire week is now just a log without anything that still needs my attention.

+ +

However, just adding a #done string will rapidly make that tag unweildly; I don’t foresee a frequent need to see quickly see every single day I’ve marked with that, unlike tags such as #urgent or #reading.

+ +

Therefore, this snippet is a tag intentionally broken by an interrupting semicolon.

+ +
"#;done": {
+    "prefix": ["@dd", ";dd"],
+    "scope": "markdown,yaml",
+    "description": "Add #;done",
+    "body": [
+        "#;done",
+    ],
+},
+
+ +

#;done;(YYYY-MM-DD)

+ +

When I have a note that has multiple tasks for a longer project, it’s often useful to know not just that something’s accomplished, but also when it was done. This snippet builds on the previous one with an automatic date annotation.

+ +
"#;done; + today's date": {
+    "prefix": ["@dtd", ";dtd"],
+    "scope": "markdown,yaml",
+    "description": "Add #;done + today's date in YYYY-MM-DD format; altered from Taskpaper format for Dendron tags",
+    "body": [
+        "#;done;($CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE)",
+    ],
+},
+
+ +

Today’s Date

+ +

VS Code’s snippets include many standard variables, making it easy to use a snippet that remembers the date better than you might. Here’ a snippet that will expand to the ISO 8601 date format—more on that below the snippet itself.

+ +
"today's date": {
+    "prefix": ["@td", ";td"],
+//    "scope": "markdown,yaml,json,dendron",
+    "description": "Add today's date in YYYY-MM-DD format",
+    "body": [
+        "$CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE",
+    ],
+},
+
+ +

ISO 8601, by the way, remains the date format for discerning nerds largely because it lists values in largest to smallest time unit and therefore has the benefit of sorting files reliably.

+ +

It’s used, for instance, for sorting posts in Jekyll, the generator I use for this very site. I just now typed ;td to invoke the snippet below into the last_modified_at value for this page. That means that once I run Jekyll again, today’s date (2023-04-01) will show up in various places on this page (which should be the top and bottom visible metadata sections of this note, unless I’ve changed the template for these pages since writing this).

+ +

The scope line is commented out in this snippet, because I personally want this snippet available everywhere in VS Code. If you want to use it but prefer to narrow the places where it will work, you’d want to delete the // comment indicators at the beginning of that line, then list only the file formats where you want this snippet to work.

+ +

For instance, if you only wanted it to work in markdown and html files, you’d want the whole snippet to instead read:

+ +
"today's date": {
+    "prefix": ["@td", ";td"],
+    "scope": "markdown,html",
+    "description": "Add today's date in YYYY-MM-DD format",
+    "body": [
+        "$CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE",
+    ],
+},
+
+ +

This Hour & Minute

+ +

This snippet will add this hour and minute in 24 hour clock format. I use it often when tracking times or writing in Dendron daily notes.

+ +
"this hour and minute": {
+    "prefix": ["@thm", ";thm"],
+    "scope": "markdown,yaml,json",
+    "description": "Add this hour and minute in 24 hour clock format",
+    "body": [
+        "$CURRENT_HOUR:$CURRENT_MINUTE",
+    ],
+},
+
+ +

Times Started and Ended

+ +

Building on the above, this snippet is useful for tracking time. When used, it will look something like {started(17:10), ended(17:35)}, useful for pomodoros or other ways of time tracking.

+ +
"times started and ended": {
+    "prefix": ["@tsae", ";tsae"],
+    "scope": "markdown,yaml,dendron",
+    "description": "Add section to track start and end times",
+    "body": [
+        "{started($1$CURRENT_HOUR:$CURRENT_MINUTE), ended($2)}",
+    ],
+},
+
+ +

HTML / CSS Snippets

+ +

Tables

+ +

Here’s a few snippets related to making more accessible HTML data tables. Each of these includes row or column headers, scope=col or scope=row indicators, and captions.

+ +

They also use the VS Code syntax for tab stops and for escaping quotation marks.

+ +

Tab stops use dollar signs followed by numbers, like $1. You indicate the first tab stop with a $1, the second with $2, and so on, then optionally indicate your snippet’s “final” tab stop with a $0. As of 2023-03-26, I’m including final tab stops in these. As I continue using them, I may or may not decide that I’ll remove those.

+ +

The "col" or "row" part of the scope= attribute needs to include the quotation marks. But including a " in the snippet itself will confuse VS Code, as it will interpret the " as the end of that line! So to clarify things for these easily-confused robots, these snippets use \ characters to escape those quotation marks. I could probably instead use single quotation marks, but decades of humanities writing in American English has apparently made double quotation marks a difficult habit to break.

+ +

Accessible HTML Table

+ +

Here’s an HTML data table that doesn’t use a <thead>.

+ +
"@table": {
+    "scope": "markdown,html,yaml",
+    "prefix": ["@tt", ";tt"],
+    "description": "html table with caption",
+    "body": [
+        "<table>",
+        "<caption>$1</caption>",
+        "  <tr>",
+        "    <th scope=\"col\">$2</th>",
+        "      <td>$3</td>",
+        "      <td>$4</td>",
+        "  </tr>",
+        "  <tr>",
+        "    <th scope=\"row\">$5</th>",
+        "      <td>$6</td>",
+        "      <td>$0</td>",
+        "  </tr>",
+        "</table>",
+    ],
+},
+
+ +

Accessible HTML Table with a <thead> +

+ +

Here’s an HTML data table that does use a <thead>.

+ +

According to WebAIM’s summary, a <thead> doesn’t add or interfere with accessibility concerns. They are handy for styling (with CSS) or for printing out long tables to paper, where any <thead> or <tfoot> rows will repeat at the top or bottom of a printed page.

+ +
"@tableh": {
+    "scope": "markdown,html,yaml",
+    "prefix": ["@tth", ";tth"],
+    "description": "html table with caption, thead, and tbody",
+    "body": [
+        "<table>",
+        "<caption>$1</caption>",
+        "<thead>",
+        "  <tr>",
+        "    <th scope=\"col\">$2</th>",
+        "      <td>$3</td>",
+        "      <td>$4</td>",
+        "  </tr>",
+        "</thead>",
+        "<tbody>",
+        "  <tr>",
+        "    <th scope=\"row\">$5</th>",
+        "      <td>$6</td>",
+        "      <td>$0</td>",
+        "  </tr>",
+        "</tbody>",
+        "</table>",
+    ],
+},
+
+ +

Accessible HTML Table Row

+ +

Once you’ve got the structure in place for a table, you’ll almost certainly want to add more rows. So here’s a snippet for beginning a row. You’ll need to add additional <td></td> indicators for each additional cell, but VS Code and most other text editors will make that pretty easy.

+ +
"@table-row": {
+    "scope": "markdown,html,yaml",
+    "prefix": ["@tr", ";tr"],
+    "description": "html table row",
+    "body": [
+        "  <tr>",
+        "    <th scope=\"row\">$1</th>",
+        "      <td>$2</td>",
+        "      <td>$0</td>",
+        "  </tr>",
+    ],
+},
+
+ +

Jekyll Snippets

+ +

Here’s a link to more notes on Jekyll.

+ +

Date, Time, and Offset

+ +

If you’re publishing more than one post a day in Jekyll, it’s handy to indicate the specific time in the date value of each post’s front matter metadata section. The time format Jekyll uses isn’t difficult to remember, but it’s also exactly the sort of thing I’d prefer to have robots do for me. Another perfect candidate for a snippet!

+ +

The output looks like this: 2023-04-01T19:14:39-6:00

+ +
"date and time for jekyll": {
+    "prefix": [";dtj"],
+    "scope": "markdown,yaml,json",
+    "description": "Add today's date, and this hour, minute, and second in 24 hour clock format, with 6 hour Boise timezone offset",
+    "body": [
+        "$CURRENT_YEAR-$CURRENT_MONTH-${CURRENT_DATE}T$CURRENT_HOUR:$CURRENT_MINUTE:$CURRENT_SECOND-6:00",
+    ],
+},
+
+ +

If you’re paying close attention, you’ll notice that one of those variable names is enclosed by curly brackets.

+ +

Here’s that variable, and the relevant section: ${CURRENT_DATE}T$CURRENT_HOUR.

+ +

Without the curly brackets, that part of the snippet would look like $CURRENT_DATET$CURRENT_HOUR. Written this way, VS Code would think you’re asking for $CURRENT_DATET, a variable that doesn’t exist.

+ +

In that unhappy version, the output you’ll get is: 2023-04-CURRENT_DATET19:24:52-6:00. Bummer.

+ +

Using the curly brackets tells VS Code that the letter T isn’t part of the variable name. In this scenario, it also lets it be output without a preceding space.

+ +

You don’t have to enclose every variable’s name in this way, but this works as a nice example of when you’d want to do so.

+ +
+ + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ +
+ + + + + + + + + + +
+ Created: +
+ + +
+ Updated: +
+ +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Technology/VS-Code/vs-code-spellcheck-squiggles.html b/notes/Technology/VS-Code/vs-code-spellcheck-squiggles.html new file mode 100644 index 000000000..45acbb268 --- /dev/null +++ b/notes/Technology/VS-Code/vs-code-spellcheck-squiggles.html @@ -0,0 +1,613 @@ + + + + + + +VS Code Spellcheck Squiggles — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + Technology / + + + + VS Code / + + + + vs code spellcheck squiggles + + +
+ + +
Created: +
+ + + +

Note status: :herb:

+ + +
+ +

There are a number of spellchecking extensions available for VS Code. I realized recently that I’d disabled the spellcheck I installed because of how distracting I found VS Code’s default squiggly lines.

+ +

So I set about making them less intrusive, but still easily perceptible.

+ +

Step 1: Check the Notification Class

+ +

Step 1 is to check the settings of whatever spell check extension you use to learn the notification class it applies.

+ +

I use Bartosz Antosik’s Spell Right, which works offline and allows for multiple languages. You can find the right setting by clicking on the “settings” gear icon, then searching for “Notification Class.”

+ +
+ Default with distracting color
+ Default spellcheck line color, which I find distracting. + +
+ +

I knew I was on the right track when I set the notification class to “warning” rather than “error” and saw the color of the squiggly lines change. But I didn’t love that color.

+ +

I liked the default “hint” option better, but suspected that I wouldn’t notice the indicators reliably.

+ +
+ Hint otion with grey ellipses under first characters of an error instead of full underline
+ Hint option, which I don’t find readily perceptible. + +
+ +

Step 2: Indicate Your Preferred Color

+ +

Step 2 is to open your settings.json file, then add your preferred color’s hex code… and do so in the right place.

+ +
+ Squiggly underline in my preferred color
+ Here’s my preference, noticeable but not distracting in multiples. + +
+ +

You have to add "editorWarning.foreground": "#(your color hex here w/o parentheses)", in the “workbench.colorCustomizations” section. Not in the “editor.tokenColorCustomizations” section! (Which is the mistake that took me a while to find.)

+ +

Step 3: Determine Your Preferred Color

+ +

But what if you don’t love your theme’s default colors?

+ +

Step 3 is to learn that ColorHexa exists. You can use that site’s color blend tool to combine your theme’s colors into one that is perceptible, jibes with your aesthetics, but isn’t jarring. Then add that new, less jarring color to your "editorWarning.foreground" setting as mentioned above.

+ +
+ + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ + + + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Technology/VS-Code/vs-code.html b/notes/Technology/VS-Code/vs-code.html new file mode 100644 index 000000000..2297f4516 --- /dev/null +++ b/notes/Technology/VS-Code/vs-code.html @@ -0,0 +1,595 @@ + + + + + + +VS Code note — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + + +
+ + +
+ + + + +
+ +
+ + home / + + + notes / + + + + Technology / + + + + VS Code / + + + + vs code + + +
+ + +
Created: +
+ + +
Updated: +
+ + +

Note status: :seedling:

+ + +
+ +

Here’s where I’ll detail aspects of how I set up and use of VS Code, which I adopted so I could use Dendron in particular. You can learn more about how I use Dendron in literature notes in dendron.

+ +
+ + + + +
+
+ +
+ + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + +
+ +
+ + + + + + + + + + +
+ Created: +
+ + +
+ Updated: +
+ +
+ + + + + + +
+ + +
+ + + + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/Technology/index.html b/notes/Technology/index.html new file mode 100644 index 000000000..624467e03 --- /dev/null +++ b/notes/Technology/index.html @@ -0,0 +1,582 @@ + + + + + + +Technology — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+
+ + + + + +
+ + + + + + + + + +
+ +
+

Technology +

+ + + +
+ + +
+ + + + +
+ +
+
a wonky wiki, a digital garden
+
+
+ +
+ + home / + + + notes / + + + + Technology / + + + + index + + +
+ +

All Technology folders

+ + + + + + + + +
+ + +
+ VS Code +
+
+ + + + + +

All Technology items

+ + + + + +
+
+
+:seedling: = emerging note
+
+:herb: = established note
+
:evergreen_tree: = evergreen note
+
+
+ + + + + +
+ +
+ + + + + + +
+ Created: +
+ + +
+ + + +
+ + +
+ + + +
+
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/beginning-to-use-obsidian.html b/notes/beginning-to-use-obsidian.html new file mode 100644 index 000000000..c2cf158d8 --- /dev/null +++ b/notes/beginning-to-use-obsidian.html @@ -0,0 +1,641 @@ + + + + + + +I’ve Been Using Obsidian — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ +
+

+ +

+ + +

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

+ + +
+ + +
+ + +

I’ve been using Obsidian, the app for linked notes.

+ +

I’ve written a note with some first thoughts, and I’m planning to write more already.

+ + +

Like all my other notes, I'll continually update this one, and only mention it again on this blog if I make sufficiently mentionable changes.

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

+ Categories: + + + + + +

+ + + + +
Created:
+ + +
+ + + + + + +
+ + +
+ + + + + + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/emerging-notes.html b/notes/emerging-notes.html new file mode 100644 index 000000000..383155be2 --- /dev/null +++ b/notes/emerging-notes.html @@ -0,0 +1,607 @@ + + + + + + +Emerging Notes — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+
+ + + + + +
+ + + + + + + + + +
+ +
+

Emerging Notes +

+ + + +
+ + +
+ + + + +
+ +
+
a wonky wiki, a digital garden
+
+
+ +
+ + home / + + + notes / + + + + emerging notes + + +
+ +

Welcome to my notes!

+

This is my digital garden—a loosely tended succulent collection. Pathways of thought represented via pixels, all perpetually in process. Show yourself around!

+ + + + + +

+:seedling: Emerging Notes

+ +
  • +_notes/ADHD-tech/about-ADHD-technologies.md :seedling: +
  • + +
  • +_notes/Accessibility/math-a11y.md :seedling: +
  • + +
  • +_notes/Note-taking/Approaches/casey-boyle-something-like-reading-ethics.md :seedling: +
  • + +
  • +_notes/Note-taking/Approaches/rhetorical-precis.md :seedling: +
  • + +
  • +_notes/Note-taking/Dendron/beginning-to-use-dendron.md :seedling: +
  • + +
  • +_notes/Note-taking/Dendron/literature-notes-dendron.md :seedling: +
  • + +
  • +_notes/Note-taking/Dendron/task-tracking-in-dendron.md :seedling: +
  • + +
  • +_notes/Note-taking/Obsidian/beginning-to-use-obsidian.md :seedling: +
  • + +
  • +_notes/Snippets/information-informatics.md :seedling: +
  • + +
  • +_notes/Technology/Jekyll/jekyll-guides.md :seedling: +
  • + +
  • +_notes/Technology/Social-Media/mastodon-apps.md :seedling: +
  • + +
  • +_notes/Technology/Social-Media/mastodon-settings.md :seedling: +
  • + +
  • +_notes/Technology/VS-Code/vs-code.md :seedling: +
  • + + +

    +:herb: Established Notes

    + +
  • +_notes/ADHD-tech/apple-watch-ADHD.md :herb: +
  • + +
  • +_notes/Note-taking/Obsidian/obsidian-plugins.md :herb: +
  • + +
  • +_notes/Note-taking/Obsidian/obsidian-tasks-plugin-patterns.md :herb: +
  • + +
  • +_notes/Reading/Articles/riggs-and-linder-actively-engaging-students.md :herb: +
  • + +
  • +_notes/Reading/Books/hall-policing-the-crisis.md :herb: +
  • + +
  • +_notes/Reading/Books/lee-overwhelmed.md :herb: +
  • + +
  • +_notes/Reading/Books/purdon-modernist-informatics.md :herb: +
  • + +
  • +_notes/Reading/Books/wark-capital-is-dead.md :herb: +
  • + +
  • +_notes/Technology/VS-Code/daybreak-theme.md :herb: +
  • + +
  • +_notes/Technology/VS-Code/vs-code-snippets.md :herb: +
  • + +
  • +_notes/Technology/VS-Code/vs-code-spellcheck-squiggles.md :herb: +
  • + + +

    +:evergreen_tree: Evergreen Notes

    + + +
    +
    +
    +:seedling: = emerging note
    +
    +:herb: = established note
    +
    :evergreen_tree: = evergreen note
    +
    +
    + + + + + +
    + +
    + + + + + + +
    + Created: +
    + + +
    + + + +
    + + +
    + + + +
    +
    + + +
    +
    +
    + + +
    +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/index.html b/notes/index.html new file mode 100644 index 000000000..30a526002 --- /dev/null +++ b/notes/index.html @@ -0,0 +1,893 @@ + + + + + + +Notes Index — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    +
    + + + + + +
    + + + + + + + + + +
    + +
    +

    Notes Index +

    + + + +
    + + +
    + + + + +
    + +
    +
    a wonky wiki, a digital garden
    +
    +
    + +
    + + home / + + + notes / + + + + index + + +
    + +

    Welcome to my notes!

    +

    This is my digital garden—a loosely tended succulent collection. Pathways of thought represented via pixels, all perpetually in process. Show yourself around!

    + +

    All folders

    + + + + + + + + +
    + + +
    + ADHD + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +

    +:house_with_garden: All my notes

    +
    + +
    +
    + + + + + +

    +:seedling: Emerging Notes

    + + +
    + +

    +:herb: Established Notes

    + + +
    + +

    +:evergreen_tree: Evergreen Notes

    +
    + +

    There are no evergreen notes yet!

    + +
    +
    + +
    +
    +
    +:seedling: = emerging note
    +
    +:herb: = established note
    +
    :evergreen_tree: = evergreen note
    +
    +
    + + + + + +
    + +
    + + + + + + +
    + Created: +
    + + +
    + + + +
    + + +
    + + + +
    +
    + + +
    +
    +
    + + +
    +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/jekyll-guides-note.html b/notes/jekyll-guides-note.html new file mode 100644 index 000000000..5bd271325 --- /dev/null +++ b/notes/jekyll-guides-note.html @@ -0,0 +1,639 @@ + + + + + + +New note on Jekyll Guides — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + +

    I’ve just made a new note where I’ll keep annotated links to particularly useful Jekyll guides.

    + + +

    Like all my other notes, I'll continually update this one, and only mention it again on this blog if I make sufficiently mentionable changes.

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

    + Categories: + + + + + +

    + + + + +
    Created:
    + + +
    + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/new-note-beginning-to-use-dendron.html b/notes/new-note-beginning-to-use-dendron.html new file mode 100644 index 000000000..dda88cdcf --- /dev/null +++ b/notes/new-note-beginning-to-use-dendron.html @@ -0,0 +1,639 @@ + + + + + + +New note on beginning to use Dendron — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + +

    I’ve just made a new note where I’ll keep suggestions for beginning to use Dendron.

    + + +

    Like all my other notes, I'll continually update this one, and only mention it again on this blog if I make sufficiently mentionable changes.

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

    + Categories: + + + + + +

    + + + + +
    Created:
    + + +
    + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/new-note-on-adhd-technologies.html b/notes/new-note-on-adhd-technologies.html new file mode 100644 index 000000000..277535b69 --- /dev/null +++ b/notes/new-note-on-adhd-technologies.html @@ -0,0 +1,639 @@ + + + + + + +New note on ADHD technologies — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + +

    I just published a new note on ADHD technologies in my digital garden / wonky wiki. It’s one of my first!

    + + +

    Like all my other notes, I'll continually update this one, and only mention it again on this blog if I make sufficiently mentionable changes.

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

    + Categories: + + + + + +

    + + + + +
    Created:
    + + +
    + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/new-note-on-apple-watch-and-adhd.html b/notes/new-note-on-apple-watch-and-adhd.html new file mode 100644 index 000000000..41eef4d9c --- /dev/null +++ b/notes/new-note-on-apple-watch-and-adhd.html @@ -0,0 +1,639 @@ + + + + + + +New note on Apple Watches and ADHD — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + +

    I just published a new note on Apple Watches and ADHD in my digital garden / wonky wiki. It’s one of my first!

    + + +

    Like all my other notes, I'll continually update this one, and only mention it again on this blog if I make sufficiently mentionable changes.

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

    + Categories: + + + + + +

    + + + + +
    Created:
    + + +
    + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/new-note-on-casey-boyles-something-like-a-reading-ethics.html b/notes/new-note-on-casey-boyles-something-like-a-reading-ethics.html new file mode 100644 index 000000000..b9e356441 --- /dev/null +++ b/notes/new-note-on-casey-boyles-something-like-a-reading-ethics.html @@ -0,0 +1,639 @@ + + + + + + +New note on Casey Boyle’s …something like a reading ethics… — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + +

    I’ve just made a new note about Casey Boyle’s …something like a reading ethics…, which is a very useful approach to reading and taking notes.

    + + +

    Like all my other notes, I'll continually update this one, and only mention it again on this blog if I make sufficiently mentionable changes.

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

    + Categories: + + + + + +

    + + + + +
    Created:
    + + +
    + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/new-note-on-informatics-readings.html b/notes/new-note-on-informatics-readings.html new file mode 100644 index 000000000..dd67ce316 --- /dev/null +++ b/notes/new-note-on-informatics-readings.html @@ -0,0 +1,639 @@ + + + + + + +New note on reading snippets about Information and Informatics — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + +

    I just published a new note with some snippets about information and informatics in my digital garden / wonky wiki.

    + + +

    Like all my other notes, I'll continually update this one, and only mention it again on this blog if I make sufficiently mentionable changes.

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

    + Categories: + + + + + +

    + + + + +
    Created:
    + + +
    + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/new-note-on-keeping-literature-notes-in-dendron.html b/notes/new-note-on-keeping-literature-notes-in-dendron.html new file mode 100644 index 000000000..f2bb4a058 --- /dev/null +++ b/notes/new-note-on-keeping-literature-notes-in-dendron.html @@ -0,0 +1,639 @@ + + + + + + +New note on keeping literature notes in Dendron — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + +

    I’ve just made a new note about how I keep literature notes in Dendron.

    + + +

    Like all my other notes, I'll continually update this one, and only mention it again on this blog if I make sufficiently mentionable changes.

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

    + Categories: + + + + + +

    + + + + +
    Created:
    + + +
    + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/new-note-on-mastodon-ios-apps.html b/notes/new-note-on-mastodon-ios-apps.html new file mode 100644 index 000000000..426983f1a --- /dev/null +++ b/notes/new-note-on-mastodon-ios-apps.html @@ -0,0 +1,639 @@ + + + + + + +New note on Mastodon iOS apps — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + +

    I’ve just made a new note where I’ll keep annotated links to particularly useful Jekyll guides.

    + + +

    Like all my other notes, I'll continually update this one, and only mention it again on this blog if I make sufficiently mentionable changes.

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

    + Categories: + + + + + +

    + + + + +
    Created:
    + + +
    + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/new-note-on-mastodon-settings.html b/notes/new-note-on-mastodon-settings.html new file mode 100644 index 000000000..e1e76a7a1 --- /dev/null +++ b/notes/new-note-on-mastodon-settings.html @@ -0,0 +1,639 @@ + + + + + + +New note on Mastodon Settings — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + +

    I’ve just made a new note where I’ll keep annotated links to particularly useful Jekyll guides.

    + + +

    Like all my other notes, I'll continually update this one, and only mention it again on this blog if I make sufficiently mentionable changes.

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

    + Categories: + + + + + +

    + + + + +
    Created:
    + + +
    + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/new-note-on-math-accessibility.html b/notes/new-note-on-math-accessibility.html new file mode 100644 index 000000000..f40fc0ec7 --- /dev/null +++ b/notes/new-note-on-math-accessibility.html @@ -0,0 +1,639 @@ + + + + + + +New note on math accessibility — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + +

    I’ve written a new note with what I’ve recently learned about ways to make equations and other math notation more accessible online.

    + + +

    Like all my other notes, I'll continually update this one, and only mention it again on this blog if I make sufficiently mentionable changes.

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

    + Categories: + + + + + +

    + + + + +
    Created:
    + + +
    + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/new-note-on-rhetorical-precis.html b/notes/new-note-on-rhetorical-precis.html new file mode 100644 index 000000000..21e810f38 --- /dev/null +++ b/notes/new-note-on-rhetorical-precis.html @@ -0,0 +1,639 @@ + + + + + + +New note on Rhetorical Précis — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + +

    I’ve just made a new note about the rhetorical précis format for taking reading notes.

    + + +

    Like all my other notes, I'll continually update this one, and only mention it again on this blog if I make sufficiently mentionable changes.

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

    + Categories: + + + + + +

    + + + + +
    Created:
    + + +
    + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/new-note-on-snippets-and-vs-code.html b/notes/new-note-on-snippets-and-vs-code.html new file mode 100644 index 000000000..541d7ec0d --- /dev/null +++ b/notes/new-note-on-snippets-and-vs-code.html @@ -0,0 +1,641 @@ + + + + + + +New note on Snippets and VS Code — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + +

    Last week I made a new note about some snippets I often use, both in VS Code and other places.

    + +

    I’m continuing to update the note with additional snippets. In fact, I just added three about time and dates.

    + + +

    Like all my other notes, I'll continually update this one, and only mention it again on this blog if I make sufficiently mentionable changes.

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

    + Categories: + + + + + +

    + + + + +
    Created:
    + + +
    + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/new-note-on-spellcheck-squiggles-in-vs-code.html b/notes/new-note-on-spellcheck-squiggles-in-vs-code.html new file mode 100644 index 000000000..f0f7cb3db --- /dev/null +++ b/notes/new-note-on-spellcheck-squiggles-in-vs-code.html @@ -0,0 +1,643 @@ + + + + + + +New note on Spellcheck Squiggles in VS Code — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + +

    I made a new note about spellcheck squiggles in VS Code, and how to make them just perceptible enough.

    + + +

    Like all my other notes, I'll continually update this one, and only mention it again on this blog if I make sufficiently mentionable changes.

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

    + Categories: + + + + + +

    + + + + +
    Created:
    + + +
    Updated:
    + +
    + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/new-note-on-task-tracking-in-dendron.html b/notes/new-note-on-task-tracking-in-dendron.html new file mode 100644 index 000000000..f0d107fbd --- /dev/null +++ b/notes/new-note-on-task-tracking-in-dendron.html @@ -0,0 +1,639 @@ + + + + + + +New note on task tracking in Dendron — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + +

    I just published a new note on how I track tasks in Dendron in my digital garden / wonky wiki.

    + + +

    Like all my other notes, I'll continually update this one, and only mention it again on this blog if I make sufficiently mentionable changes.

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

    + Categories: + + + + + +

    + + + + +
    Created:
    + + +
    + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/new-note-on-the-daybreak-theme.html b/notes/new-note-on-the-daybreak-theme.html new file mode 100644 index 000000000..a3dfd8674 --- /dev/null +++ b/notes/new-note-on-the-daybreak-theme.html @@ -0,0 +1,639 @@ + + + + + + +New note on the Daybreak theme for VS Code — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + +

    I’ve just made a new note about the Daybreak theme for VS Code, and my customizations to it.

    + + +

    Like all my other notes, I'll continually update this one, and only mention it again on this blog if I make sufficiently mentionable changes.

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

    + Categories: + + + + + +

    + + + + +
    Created:
    + + +
    + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/new-note-on-vs-code.html b/notes/new-note-on-vs-code.html new file mode 100644 index 000000000..aa5d1722e --- /dev/null +++ b/notes/new-note-on-vs-code.html @@ -0,0 +1,639 @@ + + + + + + +New note on the VS Code editor — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + +

    I’ve just made a new note about the VS Code text editor, and why I like it.

    + + +

    Like all my other notes, I'll continually update this one, and only mention it again on this blog if I make sufficiently mentionable changes.

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

    + Categories: + + + + + +

    + + + + +
    Created:
    + + +
    + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/obsidian-plugins.html b/notes/obsidian-plugins.html new file mode 100644 index 000000000..c95506a3b --- /dev/null +++ b/notes/obsidian-plugins.html @@ -0,0 +1,641 @@ + + + + + + +My Obsidian plugins shortlist — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + +

    Over the weekend, I wrote a note with a short list of the Obsidian plugins that do the most to make it feel like “my” notes.

    + +

    I’m already planning to detail some of these further in separate notes. If that’s somehow your sort of preferred reading, stay tuned!

    + + +

    Like all my other notes, I'll continually update this one, and only mention it again on this blog if I make sufficiently mentionable changes.

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

    + Categories: + + + + + +

    + + + + +
    Created:
    + + +
    + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/notes/obsidian-tasks-patterns.html b/notes/obsidian-tasks-patterns.html new file mode 100644 index 000000000..837d2fa82 --- /dev/null +++ b/notes/obsidian-tasks-patterns.html @@ -0,0 +1,642 @@ + + + + + + +Obsidian Tasks patterns — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + +

    As I’ve mentioned a few times, I began using Obsidian earlier this year. Ultimately, the Tasks plugin was what convinced me to adopt it, despite my fondness for Dendron and my general hesitations/frustrations about Obsidian.

    + +

    It took quite a bit of delving into the Obsidian Discord forums and subsequent experimentation to figure out some of the queries and filters that best suit my brain.

    + +

    If you’re considering using a Markdown-related tool for tracking tasks, you might take a look at my note on the Obsidian Tasks plugin patterns I’ve found most useful.

    + + +

    Like all my other notes, I'll continually update this one, and only mention it again on this blog if I make sufficiently mentionable changes.

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

    + Categories: + + + + + +

    + + + + +
    Created:
    + + +
    + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/now/index.html b/now/index.html new file mode 100644 index 000000000..d277fad37 --- /dev/null +++ b/now/index.html @@ -0,0 +1,458 @@ + + + + + + +Now — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

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

    What I’m Doing Currently

    + +

    Here’s some of what I’m currently doing, as of Summer 2023.

    +
      +
    • I’m re-learning Spanish as part of my Ph.D. program requirements. I haven’t formally used Spanish since junior year of high school… back when Tupac was still alive. Since then I’ve studied Latin for my undergrad program, and then French (for reading purposes only) for my English MA program. Between those, I’m able to get the gist of most Romance languages. I’m definitely stoked to be re-learning Spanish, though! Maybe I’ll end up reading some of Manuel Castells’ works for the dissertation project, or other academic things, in addition to just being closer to verbally fluent again?
    • +
    • I’m still using the free, open-source notetaking tool Dendron, even though it’s moved from active development to primarily being in a “maintenance mode.” I’ve got my eye on Obsidian, should I ever need to switch, but I’ve decided that I like Dendron and VS Code enough that I’m not going to move until something makes me do so.
    • +
    • Continuing my first viewing of Star Trek. We started with Deep Space Nine, then went to the original series, and have continued watching all the series and movies in order. At this point we’re up to the first season of Voyager.
    • +
    + +

    Right About /Now

    + +

    This page is inspired by Derek Sivers’s /now page.

    + +

    The Long /Now

    + +

    You can view this page’s source history.

    + + + + +
    + +
    + + + + + + + + + + +
    Created:
    + + +
    Updated:
    + +
    + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/page10/index.html b/page10/index.html new file mode 100644 index 000000000..c31eeaf40 --- /dev/null +++ b/page10/index.html @@ -0,0 +1,746 @@ + + + + + + +Ryan P. Randall — Page 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + +
    + + + + +
    + + + + + +
    + +
    + + + + +
    + + +
    + + + + +

    About Me

    + +

    As an Instructional Designer at Idaho State University, I work to help faculty design engaging, clear, and accessible online courses that improve outcomes for every learner. I'm enthusiastic about open educational resources (OERs) and open pedagogical approaches.

    + +

    I'm also a student in Idaho State University's Ph.D. in English and the Teaching of English program, which emphasizes pedagogy more than most English literature programs. I serve as the Web Editor for In the Library with the Lead Pipe, an open access, open peer reviewed library journal.

    + +

    In my previous role as the Instruction Coordinator and Faculty Outreach Librarian for the College of Western Idaho, I worked with students, other librarians, faculty, and staff to promote critical information literacy and library use.

    + +

    Prior to librarianship, I earned an MA in English from the University of California, Riverside and an MA in Visual and Cultural Studies from the University of Rochester. While a graduate student, then as an adjunct, I taught what librarians call information literacy skills as the instructor for many first-year writing seminar courses and lower-division American Studies and Film/Media courses. I was also a college writing tutor for undergraduate and graduate students. The path of librarianship took me to IU Bloomington's MLS program, where my favorite courses emphasized critical information literacy, humanities subject librarianship, and digital humanities.

    + +

    Outside of that more clearly academic stuff, I've hosted a college radio show on KUCR & WRUR, been in a band or two, and learned from participation and collective study in various do-it-ourselves communities. If you're looking for communities related to librarianship, you might start by checking out #critlib, The Librarian Parlor, and Hack Library School, each of which I often look to for insights.

    + +

    CV

    + +

    If all of this somehow leaves your curiosity unsated, here's my CV.

    + +

    Other Pages

    + + +

    Featured Posts

    + +
    + +

    critlib #feelings

    +

    Why do I #critlib? Because another librarianship is possible.

    + + +
    + +
    + +

    Freire and Critical Librarianship

    +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship.

    + + +
    + + +

    Recent posts

    + + + + + + + + +
    + +

    WA 2016 Week 07: Tools for Thinking

    +

    Tools for Thinking (for information literacy instruction) and Tech Tools for Keeping Thoughts in Order (using Atom and its packages)

    + + +
    + + + + + + + + + + + + + + + + + +
    + + + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/page11/index.html b/page11/index.html new file mode 100644 index 000000000..abde647e9 --- /dev/null +++ b/page11/index.html @@ -0,0 +1,746 @@ + + + + + + +Ryan P. Randall — Page 11 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + +
    + + + + +
    + + + + + +
    + +
    + + + + +
    + + +
    + + + + +

    About Me

    + +

    As an Instructional Designer at Idaho State University, I work to help faculty design engaging, clear, and accessible online courses that improve outcomes for every learner. I'm enthusiastic about open educational resources (OERs) and open pedagogical approaches.

    + +

    I'm also a student in Idaho State University's Ph.D. in English and the Teaching of English program, which emphasizes pedagogy more than most English literature programs. I serve as the Web Editor for In the Library with the Lead Pipe, an open access, open peer reviewed library journal.

    + +

    In my previous role as the Instruction Coordinator and Faculty Outreach Librarian for the College of Western Idaho, I worked with students, other librarians, faculty, and staff to promote critical information literacy and library use.

    + +

    Prior to librarianship, I earned an MA in English from the University of California, Riverside and an MA in Visual and Cultural Studies from the University of Rochester. While a graduate student, then as an adjunct, I taught what librarians call information literacy skills as the instructor for many first-year writing seminar courses and lower-division American Studies and Film/Media courses. I was also a college writing tutor for undergraduate and graduate students. The path of librarianship took me to IU Bloomington's MLS program, where my favorite courses emphasized critical information literacy, humanities subject librarianship, and digital humanities.

    + +

    Outside of that more clearly academic stuff, I've hosted a college radio show on KUCR & WRUR, been in a band or two, and learned from participation and collective study in various do-it-ourselves communities. If you're looking for communities related to librarianship, you might start by checking out #critlib, The Librarian Parlor, and Hack Library School, each of which I often look to for insights.

    + +

    CV

    + +

    If all of this somehow leaves your curiosity unsated, here's my CV.

    + +

    Other Pages

    + + +

    Featured Posts

    + +
    + +

    critlib #feelings

    +

    Why do I #critlib? Because another librarianship is possible.

    + + +
    + +
    + +

    Freire and Critical Librarianship

    +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship.

    + + +
    + + +

    Recent posts

    + + +
    + +

    WA 2016 Week 04: Library Privacy

    +

    Library privacy session with ACLU Idaho’s Ritchie Eppink and Library Freedom Project’s Alison Macrina at Meridian Library District’s unBound technology lab.

    + + +
    + + + + + +
    + +

    WA 2016 Week 02: Giroux on Neutrality

    +

    A culture of positivism, distinguishing between objectivity and objectivism, hegemony, false neutrality, values—this article has all sorts of relevance for librarianship!

    + + +
    + + + + + +
    + +

    Weekly Whaaa…?

    +

    Why weekly? Why assemblage? Why Fluxus? And what’s that “sous les pavés, la plage” thing about?

    + + +
    + + + + + + + + + + + +
    + + + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/page12/index.html b/page12/index.html new file mode 100644 index 000000000..9851efd34 --- /dev/null +++ b/page12/index.html @@ -0,0 +1,746 @@ + + + + + + +Ryan P. Randall — Page 12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + +
    + + + + +
    + + + + + +
    + +
    + + + + +
    + + +
    + + + + +

    About Me

    + +

    As an Instructional Designer at Idaho State University, I work to help faculty design engaging, clear, and accessible online courses that improve outcomes for every learner. I'm enthusiastic about open educational resources (OERs) and open pedagogical approaches.

    + +

    I'm also a student in Idaho State University's Ph.D. in English and the Teaching of English program, which emphasizes pedagogy more than most English literature programs. I serve as the Web Editor for In the Library with the Lead Pipe, an open access, open peer reviewed library journal.

    + +

    In my previous role as the Instruction Coordinator and Faculty Outreach Librarian for the College of Western Idaho, I worked with students, other librarians, faculty, and staff to promote critical information literacy and library use.

    + +

    Prior to librarianship, I earned an MA in English from the University of California, Riverside and an MA in Visual and Cultural Studies from the University of Rochester. While a graduate student, then as an adjunct, I taught what librarians call information literacy skills as the instructor for many first-year writing seminar courses and lower-division American Studies and Film/Media courses. I was also a college writing tutor for undergraduate and graduate students. The path of librarianship took me to IU Bloomington's MLS program, where my favorite courses emphasized critical information literacy, humanities subject librarianship, and digital humanities.

    + +

    Outside of that more clearly academic stuff, I've hosted a college radio show on KUCR & WRUR, been in a band or two, and learned from participation and collective study in various do-it-ourselves communities. If you're looking for communities related to librarianship, you might start by checking out #critlib, The Librarian Parlor, and Hack Library School, each of which I often look to for insights.

    + +

    CV

    + +

    If all of this somehow leaves your curiosity unsated, here's my CV.

    + +

    Other Pages

    + + +

    Featured Posts

    + +
    + +

    critlib #feelings

    +

    Why do I #critlib? Because another librarianship is possible.

    + + +
    + +
    + +

    Freire and Critical Librarianship

    +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship.

    + + +
    + + +

    Recent posts

    + + +
    + +

    critlib #feelings

    +

    Why do I #critlib? Because another librarianship is possible.

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

    WA 2015 Week 46 Massumi and North

    +

    Enthusiasm about Massumi putting Deleuze in a nutshell! Analogies between the pedagogy & structural place of Writing Centers & libraries! Jekyll on the Run!

    + + +
    + + + + + + + + + + + +
    + + + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/page13/index.html b/page13/index.html new file mode 100644 index 000000000..9ebc59877 --- /dev/null +++ b/page13/index.html @@ -0,0 +1,747 @@ + + + + + + +Ryan P. Randall — Page 13 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + +
    + + + + +
    + + + + + +
    + +
    + + + + +
    + + +
    + + + + +

    About Me

    + +

    As an Instructional Designer at Idaho State University, I work to help faculty design engaging, clear, and accessible online courses that improve outcomes for every learner. I'm enthusiastic about open educational resources (OERs) and open pedagogical approaches.

    + +

    I'm also a student in Idaho State University's Ph.D. in English and the Teaching of English program, which emphasizes pedagogy more than most English literature programs. I serve as the Web Editor for In the Library with the Lead Pipe, an open access, open peer reviewed library journal.

    + +

    In my previous role as the Instruction Coordinator and Faculty Outreach Librarian for the College of Western Idaho, I worked with students, other librarians, faculty, and staff to promote critical information literacy and library use.

    + +

    Prior to librarianship, I earned an MA in English from the University of California, Riverside and an MA in Visual and Cultural Studies from the University of Rochester. While a graduate student, then as an adjunct, I taught what librarians call information literacy skills as the instructor for many first-year writing seminar courses and lower-division American Studies and Film/Media courses. I was also a college writing tutor for undergraduate and graduate students. The path of librarianship took me to IU Bloomington's MLS program, where my favorite courses emphasized critical information literacy, humanities subject librarianship, and digital humanities.

    + +

    Outside of that more clearly academic stuff, I've hosted a college radio show on KUCR & WRUR, been in a band or two, and learned from participation and collective study in various do-it-ourselves communities. If you're looking for communities related to librarianship, you might start by checking out #critlib, The Librarian Parlor, and Hack Library School, each of which I often look to for insights.

    + +

    CV

    + +

    If all of this somehow leaves your curiosity unsated, here's my CV.

    + +

    Other Pages

    + + +

    Featured Posts

    + +
    + +

    critlib #feelings

    +

    Why do I #critlib? Because another librarianship is possible.

    + + +
    + +
    + +

    Freire and Critical Librarianship

    +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship.

    + + +
    + + +

    Recent posts

    + + +
    + +

    Weekly Assemblage 2015 Week 45

    +

    Three links & lots of enthusiasm! Elmborg’s “Literacies Large and Small,” a Time Management mega post, & how STEM relates to the liberal arts.

    + + +
    + + +
    + +

    Weekly Assemblage 2015 Week 44

    +

    Halloween at CWI Library (Once Upon a Time); Readings I’m looking forward to; Taught my first library resources session.

    + + +
    + + + + + +
    + +

    Weekly Assemblage 2015 Week 42

    +

    Live! Real! Humans! (in the Classroom); Code Camps, the “Californian Ideology,” & Higher Ed’s Purpose; Open Access & “The Library of Forking Paths.”

    + + +
    + + +
    + +

    Weekly Assemblage 2015 Week 41

    +

    Talking about librarianship values: objectivity as a value and valuing inclusivity enough to work toward it in earnest. And again—sorry, Eduardo.

    + + +
    + + + + + + + + + + + +
    + + + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/page14/index.html b/page14/index.html new file mode 100644 index 000000000..d0ce62b4d --- /dev/null +++ b/page14/index.html @@ -0,0 +1,745 @@ + + + + + + +Ryan P. Randall — Page 14 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + +
    + + + + +
    + + + + + +
    + +
    + + + + +
    + + +
    + + + + +

    About Me

    + +

    As an Instructional Designer at Idaho State University, I work to help faculty design engaging, clear, and accessible online courses that improve outcomes for every learner. I'm enthusiastic about open educational resources (OERs) and open pedagogical approaches.

    + +

    I'm also a student in Idaho State University's Ph.D. in English and the Teaching of English program, which emphasizes pedagogy more than most English literature programs. I serve as the Web Editor for In the Library with the Lead Pipe, an open access, open peer reviewed library journal.

    + +

    In my previous role as the Instruction Coordinator and Faculty Outreach Librarian for the College of Western Idaho, I worked with students, other librarians, faculty, and staff to promote critical information literacy and library use.

    + +

    Prior to librarianship, I earned an MA in English from the University of California, Riverside and an MA in Visual and Cultural Studies from the University of Rochester. While a graduate student, then as an adjunct, I taught what librarians call information literacy skills as the instructor for many first-year writing seminar courses and lower-division American Studies and Film/Media courses. I was also a college writing tutor for undergraduate and graduate students. The path of librarianship took me to IU Bloomington's MLS program, where my favorite courses emphasized critical information literacy, humanities subject librarianship, and digital humanities.

    + +

    Outside of that more clearly academic stuff, I've hosted a college radio show on KUCR & WRUR, been in a band or two, and learned from participation and collective study in various do-it-ourselves communities. If you're looking for communities related to librarianship, you might start by checking out #critlib, The Librarian Parlor, and Hack Library School, each of which I often look to for insights.

    + +

    CV

    + +

    If all of this somehow leaves your curiosity unsated, here's my CV.

    + +

    Other Pages

    + + +

    Featured Posts

    + +
    + +

    critlib #feelings

    +

    Why do I #critlib? Because another librarianship is possible.

    + + +
    + +
    + +

    Freire and Critical Librarianship

    +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship.

    + + +
    + + +

    Recent posts

    + + + + + + + + +
    + +

    Weekly Assemblage 2015 Week 39

    +

    Getting library cards and appreciating some unexpected aspects of Maria Accardi’s Feminist Pedagogy for Library Instruction.

    + + +
    + + +
    + +

    Weekly Assemblage 2015 Week 38

    +

    Driving from Bloomington, Indiana to Boise, Idaho; Luciano Floridi’s Information: A Very Short Introduction.

    + + +
    + + +
    + +

    Weekly Assemblage 2015 Week 37

    +

    A #critlib chat on information & migrant populations; threats to the Tor exit node in Kilton Public Library; CFP for papers on whiteness in LIS; study on lowering white defensiveness around racial privilege.

    + + +
    + + + + + + + + + + + +
    + + + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/page15/index.html b/page15/index.html new file mode 100644 index 000000000..a3e858d0e --- /dev/null +++ b/page15/index.html @@ -0,0 +1,752 @@ + + + + + + +Ryan P. Randall — Page 15 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + +
    + + + + +
    + + + + + +
    + +
    + + + + +
    + + +
    + + + + +

    About Me

    + +

    As an Instructional Designer at Idaho State University, I work to help faculty design engaging, clear, and accessible online courses that improve outcomes for every learner. I'm enthusiastic about open educational resources (OERs) and open pedagogical approaches.

    + +

    I'm also a student in Idaho State University's Ph.D. in English and the Teaching of English program, which emphasizes pedagogy more than most English literature programs. I serve as the Web Editor for In the Library with the Lead Pipe, an open access, open peer reviewed library journal.

    + +

    In my previous role as the Instruction Coordinator and Faculty Outreach Librarian for the College of Western Idaho, I worked with students, other librarians, faculty, and staff to promote critical information literacy and library use.

    + +

    Prior to librarianship, I earned an MA in English from the University of California, Riverside and an MA in Visual and Cultural Studies from the University of Rochester. While a graduate student, then as an adjunct, I taught what librarians call information literacy skills as the instructor for many first-year writing seminar courses and lower-division American Studies and Film/Media courses. I was also a college writing tutor for undergraduate and graduate students. The path of librarianship took me to IU Bloomington's MLS program, where my favorite courses emphasized critical information literacy, humanities subject librarianship, and digital humanities.

    + +

    Outside of that more clearly academic stuff, I've hosted a college radio show on KUCR & WRUR, been in a band or two, and learned from participation and collective study in various do-it-ourselves communities. If you're looking for communities related to librarianship, you might start by checking out #critlib, The Librarian Parlor, and Hack Library School, each of which I often look to for insights.

    + +

    CV

    + +

    If all of this somehow leaves your curiosity unsated, here's my CV.

    + +

    Other Pages

    + + +

    Featured Posts

    + +
    + +

    critlib #feelings

    +

    Why do I #critlib? Because another librarianship is possible.

    + + +
    + +
    + +

    Freire and Critical Librarianship

    +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship.

    + + +
    + + +

    Recent posts

    + + + + + +
    + +

    All Hail Cloud Storage

    +

    Dropbox has both saved me from computer problems and helped me work more ubiquitously, so I sang the praises of it and other cloud storage at Hack Library School.

    + + +
    + + + + + +
    + +

    Presentation Alternatives: Reveal.js

    +

    Are you looking for a good alternative to PowerPoint or Keynotes? Here’s a Hack Library School post about an excellent free & open source one!

    + + +
    + + + + + + + + + + + + + + +
    + + + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/page16/index.html b/page16/index.html new file mode 100644 index 000000000..cb3ae6b25 --- /dev/null +++ b/page16/index.html @@ -0,0 +1,744 @@ + + + + + + +Ryan P. Randall — Page 16 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + +
    + + + + +
    + + + + + +
    + +
    + + + + +
    + + +
    + + + + +

    About Me

    + +

    As an Instructional Designer at Idaho State University, I work to help faculty design engaging, clear, and accessible online courses that improve outcomes for every learner. I'm enthusiastic about open educational resources (OERs) and open pedagogical approaches.

    + +

    I'm also a student in Idaho State University's Ph.D. in English and the Teaching of English program, which emphasizes pedagogy more than most English literature programs. I serve as the Web Editor for In the Library with the Lead Pipe, an open access, open peer reviewed library journal.

    + +

    In my previous role as the Instruction Coordinator and Faculty Outreach Librarian for the College of Western Idaho, I worked with students, other librarians, faculty, and staff to promote critical information literacy and library use.

    + +

    Prior to librarianship, I earned an MA in English from the University of California, Riverside and an MA in Visual and Cultural Studies from the University of Rochester. While a graduate student, then as an adjunct, I taught what librarians call information literacy skills as the instructor for many first-year writing seminar courses and lower-division American Studies and Film/Media courses. I was also a college writing tutor for undergraduate and graduate students. The path of librarianship took me to IU Bloomington's MLS program, where my favorite courses emphasized critical information literacy, humanities subject librarianship, and digital humanities.

    + +

    Outside of that more clearly academic stuff, I've hosted a college radio show on KUCR & WRUR, been in a band or two, and learned from participation and collective study in various do-it-ourselves communities. If you're looking for communities related to librarianship, you might start by checking out #critlib, The Librarian Parlor, and Hack Library School, each of which I often look to for insights.

    + +

    CV

    + +

    If all of this somehow leaves your curiosity unsated, here's my CV.

    + +

    Other Pages

    + + +

    Featured Posts

    + +
    + +

    critlib #feelings

    +

    Why do I #critlib? Because another librarianship is possible.

    + + +
    + +
    + +

    Freire and Critical Librarianship

    +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship.

    + + +
    + + +

    Recent posts

    + + + + + +
    + +

    Everything Counts in Affective Amounts

    +

    Week Two of #rhizo15—How we might count the affective aspects of learning? Also, what potential does Git give us for making open humanities notebooks?

    + + +
    + + +
    + +

    Hack Quirk Your Presentations

    +

    I wrote for Hack Library School about using quirky results or affordances to make your instruction sessions more engaging.

    + + +
    + + +
    + +

    Learning Subjectives

    +

    For Week One of #rhizo15, I write about my predilection for research processes over writing outcomes & whether library “neutrality” thwarts supportive demeanor.

    + + +
    + + +
    + +

    Wojnarowicz on a Sphere

    +

    Still under construction, this post will be about my process of making a map of artist David Wojnarowicz’s gallery exhibits for the NOAA Science on a Sphere.

    + + +
    + + + + + + + + + + + +
    + + + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/page17/index.html b/page17/index.html new file mode 100644 index 000000000..1e80953d3 --- /dev/null +++ b/page17/index.html @@ -0,0 +1,736 @@ + + + + + + +Ryan P. Randall — Page 17 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + +
    + + + + +
    + + + + + +
    + +
    + + + + +
    + + +
    + + + + +

    About Me

    + +

    As an Instructional Designer at Idaho State University, I work to help faculty design engaging, clear, and accessible online courses that improve outcomes for every learner. I'm enthusiastic about open educational resources (OERs) and open pedagogical approaches.

    + +

    I'm also a student in Idaho State University's Ph.D. in English and the Teaching of English program, which emphasizes pedagogy more than most English literature programs. I serve as the Web Editor for In the Library with the Lead Pipe, an open access, open peer reviewed library journal.

    + +

    In my previous role as the Instruction Coordinator and Faculty Outreach Librarian for the College of Western Idaho, I worked with students, other librarians, faculty, and staff to promote critical information literacy and library use.

    + +

    Prior to librarianship, I earned an MA in English from the University of California, Riverside and an MA in Visual and Cultural Studies from the University of Rochester. While a graduate student, then as an adjunct, I taught what librarians call information literacy skills as the instructor for many first-year writing seminar courses and lower-division American Studies and Film/Media courses. I was also a college writing tutor for undergraduate and graduate students. The path of librarianship took me to IU Bloomington's MLS program, where my favorite courses emphasized critical information literacy, humanities subject librarianship, and digital humanities.

    + +

    Outside of that more clearly academic stuff, I've hosted a college radio show on KUCR & WRUR, been in a band or two, and learned from participation and collective study in various do-it-ourselves communities. If you're looking for communities related to librarianship, you might start by checking out #critlib, The Librarian Parlor, and Hack Library School, each of which I often look to for insights.

    + +

    CV

    + +

    If all of this somehow leaves your curiosity unsated, here's my CV.

    + +

    Other Pages

    + + +

    Featured Posts

    + +
    + +

    critlib #feelings

    +

    Why do I #critlib? Because another librarianship is possible.

    + + +
    + +
    + +

    Freire and Critical Librarianship

    +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship.

    + + +
    + + +

    Recent posts

    + + +
    + +

    #critlib Makerspaces

    +

    I write about moderating a #critlib Twitter chat on the constructivist potentials and neoliberal downsides of makerspaces, as well as briefly describe the moderation process.

    + + +
    + + +
    + +

    Freire and Critical Librarianship

    +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship.

    + + +
    + + + + + + + + + + + + + + + + + + + + +
    + + + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/page18/index.html b/page18/index.html new file mode 100644 index 000000000..100805d47 --- /dev/null +++ b/page18/index.html @@ -0,0 +1,727 @@ + + + + + + +Ryan P. Randall — Page 18 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + +
    + + + + +
    + + + + + +
    + +
    + + + + +
    + + +
    + + + + +

    About Me

    + +

    As an Instructional Designer at Idaho State University, I work to help faculty design engaging, clear, and accessible online courses that improve outcomes for every learner. I'm enthusiastic about open educational resources (OERs) and open pedagogical approaches.

    + +

    I'm also a student in Idaho State University's Ph.D. in English and the Teaching of English program, which emphasizes pedagogy more than most English literature programs. I serve as the Web Editor for In the Library with the Lead Pipe, an open access, open peer reviewed library journal.

    + +

    In my previous role as the Instruction Coordinator and Faculty Outreach Librarian for the College of Western Idaho, I worked with students, other librarians, faculty, and staff to promote critical information literacy and library use.

    + +

    Prior to librarianship, I earned an MA in English from the University of California, Riverside and an MA in Visual and Cultural Studies from the University of Rochester. While a graduate student, then as an adjunct, I taught what librarians call information literacy skills as the instructor for many first-year writing seminar courses and lower-division American Studies and Film/Media courses. I was also a college writing tutor for undergraduate and graduate students. The path of librarianship took me to IU Bloomington's MLS program, where my favorite courses emphasized critical information literacy, humanities subject librarianship, and digital humanities.

    + +

    Outside of that more clearly academic stuff, I've hosted a college radio show on KUCR & WRUR, been in a band or two, and learned from participation and collective study in various do-it-ourselves communities. If you're looking for communities related to librarianship, you might start by checking out #critlib, The Librarian Parlor, and Hack Library School, each of which I often look to for insights.

    + +

    CV

    + +

    If all of this somehow leaves your curiosity unsated, here's my CV.

    + +

    Other Pages

    + + +

    Featured Posts

    + +
    + +

    critlib #feelings

    +

    Why do I #critlib? Because another librarianship is possible.

    + + +
    + +
    + +

    Freire and Critical Librarianship

    +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship.

    + + +
    + + +

    Recent posts

    + + +
    + +

    Software Carpentry Workshop Reflections

    +

    Although aimed at scientists, Software Carpentry’s workshops offer great learning experience for librarians, digital humanities folks, and anyone looking to work on digital files in groups.

    + + +
    + + +
    + +

    Review of Online Archive of California

    +

    The Online Archive of California lies somewhere between a finding aid and a digital library—and is a huge boon to researchers that would be worth emulating elsewhere.

    + + +
    + + +
    + +

    Bigfoot Spotting and Other Jekyll Adventures

    +

    A post where I describe trying—and thus far, failing—to use Bigfoot.js to make footnotes more engaging in a Jekyll/GitHub Pages blog. I’ll revisit this soon to give it another try.

    + + +
    + + +
    + +

    New Directions in Information Fluency

    +

    Brief reflections on a talk about bringing digital humanities to the reference desk, which I co-presented with Katherine Ahnberg at the New Directions in Information Fluency conference.

    + + +
    + + +
    + +

    Test One

    +

    Here’s a stellar ditty from Warp™ records that deserves being listened to with headphones or a subwoofer.

    + + +
    + + + + + + + + + + + +
    + + + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/page19/index.html b/page19/index.html new file mode 100644 index 000000000..6f4762035 --- /dev/null +++ b/page19/index.html @@ -0,0 +1,549 @@ + + + + + + +Ryan P. Randall — Page 19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + +
    + + + + +
    + + + + + +
    + +
    + + + + +
    + + +
    + + + + +

    About Me

    + +

    As an Instructional Designer at Idaho State University, I work to help faculty design engaging, clear, and accessible online courses that improve outcomes for every learner. I'm enthusiastic about open educational resources (OERs) and open pedagogical approaches.

    + +

    I'm also a student in Idaho State University's Ph.D. in English and the Teaching of English program, which emphasizes pedagogy more than most English literature programs. I serve as the Web Editor for In the Library with the Lead Pipe, an open access, open peer reviewed library journal.

    + +

    In my previous role as the Instruction Coordinator and Faculty Outreach Librarian for the College of Western Idaho, I worked with students, other librarians, faculty, and staff to promote critical information literacy and library use.

    + +

    Prior to librarianship, I earned an MA in English from the University of California, Riverside and an MA in Visual and Cultural Studies from the University of Rochester. While a graduate student, then as an adjunct, I taught what librarians call information literacy skills as the instructor for many first-year writing seminar courses and lower-division American Studies and Film/Media courses. I was also a college writing tutor for undergraduate and graduate students. The path of librarianship took me to IU Bloomington's MLS program, where my favorite courses emphasized critical information literacy, humanities subject librarianship, and digital humanities.

    + +

    Outside of that more clearly academic stuff, I've hosted a college radio show on KUCR & WRUR, been in a band or two, and learned from participation and collective study in various do-it-ourselves communities. If you're looking for communities related to librarianship, you might start by checking out #critlib, The Librarian Parlor, and Hack Library School, each of which I often look to for insights.

    + +

    CV

    + +

    If all of this somehow leaves your curiosity unsated, here's my CV.

    + +

    Other Pages

    + + +

    Featured Posts

    + +
    + +

    critlib #feelings

    +

    Why do I #critlib? Because another librarianship is possible.

    + + +
    + +
    + +

    Freire and Critical Librarianship

    +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship.

    + + +
    + + +

    Recent posts

    + + +
    + +

    New Site

    +

    A Depeche Mode reference is more interesting than Hello World, isn’t it?

    + + +
    + + + + + + + + + + + +
    + + + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/page2/index.html b/page2/index.html new file mode 100644 index 000000000..952417592 --- /dev/null +++ b/page2/index.html @@ -0,0 +1,729 @@ + + + + + + +Ryan P. Randall — Page 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + +
    + + + + +
    + + + + + +
    + +
    + + + + +
    + + +
    + + + + +

    About Me

    + +

    As an Instructional Designer at Idaho State University, I work to help faculty design engaging, clear, and accessible online courses that improve outcomes for every learner. I'm enthusiastic about open educational resources (OERs) and open pedagogical approaches.

    + +

    I'm also a student in Idaho State University's Ph.D. in English and the Teaching of English program, which emphasizes pedagogy more than most English literature programs. I serve as the Web Editor for In the Library with the Lead Pipe, an open access, open peer reviewed library journal.

    + +

    In my previous role as the Instruction Coordinator and Faculty Outreach Librarian for the College of Western Idaho, I worked with students, other librarians, faculty, and staff to promote critical information literacy and library use.

    + +

    Prior to librarianship, I earned an MA in English from the University of California, Riverside and an MA in Visual and Cultural Studies from the University of Rochester. While a graduate student, then as an adjunct, I taught what librarians call information literacy skills as the instructor for many first-year writing seminar courses and lower-division American Studies and Film/Media courses. I was also a college writing tutor for undergraduate and graduate students. The path of librarianship took me to IU Bloomington's MLS program, where my favorite courses emphasized critical information literacy, humanities subject librarianship, and digital humanities.

    + +

    Outside of that more clearly academic stuff, I've hosted a college radio show on KUCR & WRUR, been in a band or two, and learned from participation and collective study in various do-it-ourselves communities. If you're looking for communities related to librarianship, you might start by checking out #critlib, The Librarian Parlor, and Hack Library School, each of which I often look to for insights.

    + +

    CV

    + +

    If all of this somehow leaves your curiosity unsated, here's my CV.

    + +

    Other Pages

    + + +

    Featured Posts

    + +
    + +

    critlib #feelings

    +

    Why do I #critlib? Because another librarianship is possible.

    + + +
    + +
    + +

    Freire and Critical Librarianship

    +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship.

    + + +
    + + +

    Recent posts

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/page3/index.html b/page3/index.html new file mode 100644 index 000000000..4244a03d6 --- /dev/null +++ b/page3/index.html @@ -0,0 +1,736 @@ + + + + + + +Ryan P. Randall — Page 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + +
    + + + + +
    + + + + + +
    + +
    + + + + +
    + + +
    + + + + +

    About Me

    + +

    As an Instructional Designer at Idaho State University, I work to help faculty design engaging, clear, and accessible online courses that improve outcomes for every learner. I'm enthusiastic about open educational resources (OERs) and open pedagogical approaches.

    + +

    I'm also a student in Idaho State University's Ph.D. in English and the Teaching of English program, which emphasizes pedagogy more than most English literature programs. I serve as the Web Editor for In the Library with the Lead Pipe, an open access, open peer reviewed library journal.

    + +

    In my previous role as the Instruction Coordinator and Faculty Outreach Librarian for the College of Western Idaho, I worked with students, other librarians, faculty, and staff to promote critical information literacy and library use.

    + +

    Prior to librarianship, I earned an MA in English from the University of California, Riverside and an MA in Visual and Cultural Studies from the University of Rochester. While a graduate student, then as an adjunct, I taught what librarians call information literacy skills as the instructor for many first-year writing seminar courses and lower-division American Studies and Film/Media courses. I was also a college writing tutor for undergraduate and graduate students. The path of librarianship took me to IU Bloomington's MLS program, where my favorite courses emphasized critical information literacy, humanities subject librarianship, and digital humanities.

    + +

    Outside of that more clearly academic stuff, I've hosted a college radio show on KUCR & WRUR, been in a band or two, and learned from participation and collective study in various do-it-ourselves communities. If you're looking for communities related to librarianship, you might start by checking out #critlib, The Librarian Parlor, and Hack Library School, each of which I often look to for insights.

    + +

    CV

    + +

    If all of this somehow leaves your curiosity unsated, here's my CV.

    + +

    Other Pages

    + + +

    Featured Posts

    + +
    + +

    critlib #feelings

    +

    Why do I #critlib? Because another librarianship is possible.

    + + +
    + +
    + +

    Freire and Critical Librarianship

    +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship.

    + + +
    + + +

    Recent posts

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/page4/index.html b/page4/index.html new file mode 100644 index 000000000..4988e81d9 --- /dev/null +++ b/page4/index.html @@ -0,0 +1,743 @@ + + + + + + +Ryan P. Randall — Page 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + +
    + + + + +
    + + + + + +
    + +
    + + + + +
    + + +
    + + + + +

    About Me

    + +

    As an Instructional Designer at Idaho State University, I work to help faculty design engaging, clear, and accessible online courses that improve outcomes for every learner. I'm enthusiastic about open educational resources (OERs) and open pedagogical approaches.

    + +

    I'm also a student in Idaho State University's Ph.D. in English and the Teaching of English program, which emphasizes pedagogy more than most English literature programs. I serve as the Web Editor for In the Library with the Lead Pipe, an open access, open peer reviewed library journal.

    + +

    In my previous role as the Instruction Coordinator and Faculty Outreach Librarian for the College of Western Idaho, I worked with students, other librarians, faculty, and staff to promote critical information literacy and library use.

    + +

    Prior to librarianship, I earned an MA in English from the University of California, Riverside and an MA in Visual and Cultural Studies from the University of Rochester. While a graduate student, then as an adjunct, I taught what librarians call information literacy skills as the instructor for many first-year writing seminar courses and lower-division American Studies and Film/Media courses. I was also a college writing tutor for undergraduate and graduate students. The path of librarianship took me to IU Bloomington's MLS program, where my favorite courses emphasized critical information literacy, humanities subject librarianship, and digital humanities.

    + +

    Outside of that more clearly academic stuff, I've hosted a college radio show on KUCR & WRUR, been in a band or two, and learned from participation and collective study in various do-it-ourselves communities. If you're looking for communities related to librarianship, you might start by checking out #critlib, The Librarian Parlor, and Hack Library School, each of which I often look to for insights.

    + +

    CV

    + +

    If all of this somehow leaves your curiosity unsated, here's my CV.

    + +

    Other Pages

    + + +

    Featured Posts

    + +
    + +

    critlib #feelings

    +

    Why do I #critlib? Because another librarianship is possible.

    + + +
    + +
    + +

    Freire and Critical Librarianship

    +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship.

    + + +
    + + +

    Recent posts

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/page5/index.html b/page5/index.html new file mode 100644 index 000000000..c29d0b60d --- /dev/null +++ b/page5/index.html @@ -0,0 +1,747 @@ + + + + + + +Ryan P. Randall — Page 5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + +
    + + + + +
    + + + + + +
    + +
    + + + + +
    + + +
    + + + + +

    About Me

    + +

    As an Instructional Designer at Idaho State University, I work to help faculty design engaging, clear, and accessible online courses that improve outcomes for every learner. I'm enthusiastic about open educational resources (OERs) and open pedagogical approaches.

    + +

    I'm also a student in Idaho State University's Ph.D. in English and the Teaching of English program, which emphasizes pedagogy more than most English literature programs. I serve as the Web Editor for In the Library with the Lead Pipe, an open access, open peer reviewed library journal.

    + +

    In my previous role as the Instruction Coordinator and Faculty Outreach Librarian for the College of Western Idaho, I worked with students, other librarians, faculty, and staff to promote critical information literacy and library use.

    + +

    Prior to librarianship, I earned an MA in English from the University of California, Riverside and an MA in Visual and Cultural Studies from the University of Rochester. While a graduate student, then as an adjunct, I taught what librarians call information literacy skills as the instructor for many first-year writing seminar courses and lower-division American Studies and Film/Media courses. I was also a college writing tutor for undergraduate and graduate students. The path of librarianship took me to IU Bloomington's MLS program, where my favorite courses emphasized critical information literacy, humanities subject librarianship, and digital humanities.

    + +

    Outside of that more clearly academic stuff, I've hosted a college radio show on KUCR & WRUR, been in a band or two, and learned from participation and collective study in various do-it-ourselves communities. If you're looking for communities related to librarianship, you might start by checking out #critlib, The Librarian Parlor, and Hack Library School, each of which I often look to for insights.

    + +

    CV

    + +

    If all of this somehow leaves your curiosity unsated, here's my CV.

    + +

    Other Pages

    + + +

    Featured Posts

    + +
    + +

    critlib #feelings

    +

    Why do I #critlib? Because another librarianship is possible.

    + + +
    + +
    + +

    Freire and Critical Librarianship

    +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship.

    + + +
    + + +

    Recent posts

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/page6/index.html b/page6/index.html new file mode 100644 index 000000000..acfd4a9f6 --- /dev/null +++ b/page6/index.html @@ -0,0 +1,747 @@ + + + + + + +Ryan P. Randall — Page 6 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + +
    + + + + +
    + + + + + +
    + +
    + + + + +
    + + +
    + + + + +

    About Me

    + +

    As an Instructional Designer at Idaho State University, I work to help faculty design engaging, clear, and accessible online courses that improve outcomes for every learner. I'm enthusiastic about open educational resources (OERs) and open pedagogical approaches.

    + +

    I'm also a student in Idaho State University's Ph.D. in English and the Teaching of English program, which emphasizes pedagogy more than most English literature programs. I serve as the Web Editor for In the Library with the Lead Pipe, an open access, open peer reviewed library journal.

    + +

    In my previous role as the Instruction Coordinator and Faculty Outreach Librarian for the College of Western Idaho, I worked with students, other librarians, faculty, and staff to promote critical information literacy and library use.

    + +

    Prior to librarianship, I earned an MA in English from the University of California, Riverside and an MA in Visual and Cultural Studies from the University of Rochester. While a graduate student, then as an adjunct, I taught what librarians call information literacy skills as the instructor for many first-year writing seminar courses and lower-division American Studies and Film/Media courses. I was also a college writing tutor for undergraduate and graduate students. The path of librarianship took me to IU Bloomington's MLS program, where my favorite courses emphasized critical information literacy, humanities subject librarianship, and digital humanities.

    + +

    Outside of that more clearly academic stuff, I've hosted a college radio show on KUCR & WRUR, been in a band or two, and learned from participation and collective study in various do-it-ourselves communities. If you're looking for communities related to librarianship, you might start by checking out #critlib, The Librarian Parlor, and Hack Library School, each of which I often look to for insights.

    + +

    CV

    + +

    If all of this somehow leaves your curiosity unsated, here's my CV.

    + +

    Other Pages

    + + +

    Featured Posts

    + +
    + +

    critlib #feelings

    +

    Why do I #critlib? Because another librarianship is possible.

    + + +
    + +
    + +

    Freire and Critical Librarianship

    +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship.

    + + +
    + + +

    Recent posts

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

    SIFT Links

    +

    Links related to a lightning talk for the 2020 MOSS Meetup about our switch from the CRAAP test to the SIFT moves.

    + + +
    + + + + + + + + + + + + + + +
    + + + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/page7/index.html b/page7/index.html new file mode 100644 index 000000000..49e15d9f0 --- /dev/null +++ b/page7/index.html @@ -0,0 +1,747 @@ + + + + + + +Ryan P. Randall — Page 7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + +
    + + + + +
    + + + + + +
    + +
    + + + + +
    + + +
    + + + + +

    About Me

    + +

    As an Instructional Designer at Idaho State University, I work to help faculty design engaging, clear, and accessible online courses that improve outcomes for every learner. I'm enthusiastic about open educational resources (OERs) and open pedagogical approaches.

    + +

    I'm also a student in Idaho State University's Ph.D. in English and the Teaching of English program, which emphasizes pedagogy more than most English literature programs. I serve as the Web Editor for In the Library with the Lead Pipe, an open access, open peer reviewed library journal.

    + +

    In my previous role as the Instruction Coordinator and Faculty Outreach Librarian for the College of Western Idaho, I worked with students, other librarians, faculty, and staff to promote critical information literacy and library use.

    + +

    Prior to librarianship, I earned an MA in English from the University of California, Riverside and an MA in Visual and Cultural Studies from the University of Rochester. While a graduate student, then as an adjunct, I taught what librarians call information literacy skills as the instructor for many first-year writing seminar courses and lower-division American Studies and Film/Media courses. I was also a college writing tutor for undergraduate and graduate students. The path of librarianship took me to IU Bloomington's MLS program, where my favorite courses emphasized critical information literacy, humanities subject librarianship, and digital humanities.

    + +

    Outside of that more clearly academic stuff, I've hosted a college radio show on KUCR & WRUR, been in a band or two, and learned from participation and collective study in various do-it-ourselves communities. If you're looking for communities related to librarianship, you might start by checking out #critlib, The Librarian Parlor, and Hack Library School, each of which I often look to for insights.

    + +

    CV

    + +

    If all of this somehow leaves your curiosity unsated, here's my CV.

    + +

    Other Pages

    + + +

    Featured Posts

    + +
    + +

    critlib #feelings

    +

    Why do I #critlib? Because another librarianship is possible.

    + + +
    + +
    + +

    Freire and Critical Librarianship

    +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship.

    + + +
    + + +

    Recent posts

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

    WA 2017 Week 09: Badges, Type, BibTeX

    +

    Briefly linking to Emily Ford’s article about badges, a short reference about using type on the web, and getting going with a bibliography tool.

    + + +
    + + + + + + + + + + + + + + +
    + + + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/page8/index.html b/page8/index.html new file mode 100644 index 000000000..454c17fea --- /dev/null +++ b/page8/index.html @@ -0,0 +1,747 @@ + + + + + + +Ryan P. Randall — Page 8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + +
    + + + + +
    + + + + + +
    + +
    + + + + +
    + + +
    + + + + +

    About Me

    + +

    As an Instructional Designer at Idaho State University, I work to help faculty design engaging, clear, and accessible online courses that improve outcomes for every learner. I'm enthusiastic about open educational resources (OERs) and open pedagogical approaches.

    + +

    I'm also a student in Idaho State University's Ph.D. in English and the Teaching of English program, which emphasizes pedagogy more than most English literature programs. I serve as the Web Editor for In the Library with the Lead Pipe, an open access, open peer reviewed library journal.

    + +

    In my previous role as the Instruction Coordinator and Faculty Outreach Librarian for the College of Western Idaho, I worked with students, other librarians, faculty, and staff to promote critical information literacy and library use.

    + +

    Prior to librarianship, I earned an MA in English from the University of California, Riverside and an MA in Visual and Cultural Studies from the University of Rochester. While a graduate student, then as an adjunct, I taught what librarians call information literacy skills as the instructor for many first-year writing seminar courses and lower-division American Studies and Film/Media courses. I was also a college writing tutor for undergraduate and graduate students. The path of librarianship took me to IU Bloomington's MLS program, where my favorite courses emphasized critical information literacy, humanities subject librarianship, and digital humanities.

    + +

    Outside of that more clearly academic stuff, I've hosted a college radio show on KUCR & WRUR, been in a band or two, and learned from participation and collective study in various do-it-ourselves communities. If you're looking for communities related to librarianship, you might start by checking out #critlib, The Librarian Parlor, and Hack Library School, each of which I often look to for insights.

    + +

    CV

    + +

    If all of this somehow leaves your curiosity unsated, here's my CV.

    + +

    Other Pages

    + + +

    Featured Posts

    + +
    + +

    critlib #feelings

    +

    Why do I #critlib? Because another librarianship is possible.

    + + +
    + +
    + +

    Freire and Critical Librarianship

    +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship.

    + + +
    + + +

    Recent posts

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/page9/index.html b/page9/index.html new file mode 100644 index 000000000..c8741a732 --- /dev/null +++ b/page9/index.html @@ -0,0 +1,747 @@ + + + + + + +Ryan P. Randall — Page 9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + +
    + + + + +
    + + + + + +
    + +
    + + + + +
    + + +
    + + + + +

    About Me

    + +

    As an Instructional Designer at Idaho State University, I work to help faculty design engaging, clear, and accessible online courses that improve outcomes for every learner. I'm enthusiastic about open educational resources (OERs) and open pedagogical approaches.

    + +

    I'm also a student in Idaho State University's Ph.D. in English and the Teaching of English program, which emphasizes pedagogy more than most English literature programs. I serve as the Web Editor for In the Library with the Lead Pipe, an open access, open peer reviewed library journal.

    + +

    In my previous role as the Instruction Coordinator and Faculty Outreach Librarian for the College of Western Idaho, I worked with students, other librarians, faculty, and staff to promote critical information literacy and library use.

    + +

    Prior to librarianship, I earned an MA in English from the University of California, Riverside and an MA in Visual and Cultural Studies from the University of Rochester. While a graduate student, then as an adjunct, I taught what librarians call information literacy skills as the instructor for many first-year writing seminar courses and lower-division American Studies and Film/Media courses. I was also a college writing tutor for undergraduate and graduate students. The path of librarianship took me to IU Bloomington's MLS program, where my favorite courses emphasized critical information literacy, humanities subject librarianship, and digital humanities.

    + +

    Outside of that more clearly academic stuff, I've hosted a college radio show on KUCR & WRUR, been in a band or two, and learned from participation and collective study in various do-it-ourselves communities. If you're looking for communities related to librarianship, you might start by checking out #critlib, The Librarian Parlor, and Hack Library School, each of which I often look to for insights.

    + +

    CV

    + +

    If all of this somehow leaves your curiosity unsated, here's my CV.

    + +

    Other Pages

    + + +

    Featured Posts

    + +
    + +

    critlib #feelings

    +

    Why do I #critlib? Because another librarianship is possible.

    + + +
    + +
    + +

    Freire and Critical Librarianship

    +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship.

    + + +
    + + +

    Recent posts

    + + + + + +
    + +

    WA 2016 Week 17: Research Notebook is Go!

    +

    Much like with succulents, I’ve planted an offshoot of this blog to see whether it’ll take root. Open Humanities Research Notebooks—come and join the future™.

    + + +
    + + + + + + + + + + + + + + + + + + + + +
    + + + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/paper-planned-obsolescence-and-digital-libraries.html b/paper-planned-obsolescence-and-digital-libraries.html new file mode 100644 index 000000000..69f227578 --- /dev/null +++ b/paper-planned-obsolescence-and-digital-libraries.html @@ -0,0 +1,678 @@ + + + + + + +“Paper,” “Planned Obsolescence,” and Digital Libraries — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + + + +

    This post was originally an assignment for John Walsh’s “Z652 Digital Libraries” course at IU-Bloomington.

    + +

    Two talks given at IU in the last month offer insights for digital libraries, one benefiting from direct experimentation with forms of scholarly communication and sustained analysis of academic practices, while the other’s scope provides an intriguing provocation about what libraries might consider as “digital” material. On 2014-10-30, Kathleen Fitzpatrick gave a talk related to her book Planned Obsolescence as part of the celebrations of the new Scholars’ Commons. Soon after, on 2014-11-13, Nicholas Basbanes gave a talk entitled “Paper: A Defining Technology” at the Lilly Library. Surprisingly, each presentation highlighted the practices and situated use of their subject matter, a feature which makes them work well together to discuss digital libraries. Below are abstracts and screenshots of the promotional pages for each talk:

    + +

    Fitzpatrick's talk

    + +
    +

    On Thursday, October 30, the IU Libraries will be celebrating the grand opening of the Scholars’ Commons on the first floor of Wells Library East Tower.  This celebration will include a free public lecture by Kathleen Fitzpatrick in 219 Hodge Hall at 2:00 pm and a grand opening ceremony in the Scholars’ Commons at 4:00. 
    +  +Kathleen Fitzpatrick, Director of Scholarly Communication at the Modern Language Association and Visiting Research Professor of English at New York University.  Her talk, titled “Planned Obsolescence: Publishing, Technology and the Future of the Academy,” will focus on the future of scholarly communication, which, she says, undoubtedly lies online, but the most significant challenges faced in transforming scholarly practices are not technological, but instead social and institutional. How must scholars, publishers, librarians, and administrators all reconsider their ways of thinking in order to give digital scholarly communication its future? This talk will explore some of those changes and their implications for our lives and work within universities.
    +  +Immediately following this lecture, the grand opening ceremony will take place in the Scholars’ Commons, on the first floor of the Wells Library East Tower, and will feature remarks by Dean Brenda L. Johnson and Provost Lauren Robel as well as self-guided tours and refreshments.
    +  +We hope you will join us in this celebration.  

    +
    + +

    Basbanes' talk

    + +
    +

    The Friends of the Lilly Library annual meeting  will take place on November 13, at 5:30 p.m. After the general business meeting, eminent writer and bibliophile Nicholas Basbanes will present a talk titled “Paper: A Defining Technology.” A prolific writer on all things related to books and book collecting, Basbanes is the author of A Gentle Madness: Bibliophiles, Bibliomanes, and the Eternal Passion for Books, which was a finalist in 1995 for the National Book Critics Circle Award for nonfiction and was named a New York Times Notable Book of the Year. His most recent book, On Paper: The Everything of Its Two Thousand Year History (Alfred A. Knopf, 2013), was the recipient of a National Endowment for the Humanities research fellowship in 2008, and was selected as one of three finalists for the Andrew Carnegie Medal for Excellence in Nonfiction for 2014. It was also named a notable book of the year by the American Library Association, one of the best books of the year by Booklist, Kirkus Reviews, Mother Jones, and Bloomberg News, and a “favourite” book of 2013 by the National Post (Canada). A paperback edition was issued by Vintage Press in 2014. A reception will follow the talk.

    +
    + +

    Fitzpatrick and “Planned Obsolescence”

    + +

    Kathleen Fitzpatrick’s talk, “Planned Obsolescence: Publishing, Technology, and the Future of the Academy” comprised part of the opening celebrations for IU’s new Scholars’ Commons. The main threads of her talk were that book-based scholarly communication has increasingly become outmoded due both to the economics of book publishing and to the nigh-invisibility of the labor that goes into being a peer reviewer, editor, or academic publisher. She offered her own initial draft publication of Planned Obsolescence for public comments and other Media Commons projects as examples of alternate modes of scholarship that can allow for peer review to be recognized in deeper ways than with current practices.

    + +

    Furthermore, she argued that academic publishers now function more as content filters than true gatekeepers, for it is increasingly trivial to effectively “publish” one’s writing by posting it publicly online. Despite their economic death—the average academic book sells fewer than 400 copies—academic books remain in an unsettling zombie-like state, animated primarily by the crucial role they plan in tenure practices. Fitzpatrick suggests that we must change tenure committees’ exaltation of paper-printed books over other peer-reviewed forms in order to advance disciplines that have predominantly used that form for the last 60-odd years.

    + +

    This expansion of scholarly publication formats is relevant to digital libraries for a number of interconnected reasons. Librarians with technical skills can help with the publication of academic works online, of course. More generally, librarians can also help online scholarly practices become more common and respected within academia by demonstrating how they allow for extra affordances that paper does not. Fitzpatrick mentioned how online communication can help reveal the labor obscured in traditional academic publishing practices, but online publications can also make academic work more readily accessible to screen readers and similar technologies. Additionally, helping budding researchers distinguish between quality, peer-reviewed scholarship that will have credence in their fields and something masquerading as such will remain a core part of instruction, both for librarians and traditional faculty, for as long as these differences matter.

    + +

    In addition to indirectly bolstering the role that librarians can play for academic publishing, Fitzpatrick’s talk has implications for the creators of online projects. She argues that communities engage far more around open, in-process work than around finished products, using her own born-digital publication of Planned Obsolescence as a commentable online text as an example. While scholars like Michael Warner contend that every text rhetorically invokes a public, online resources do so demonstrably. Above and beyond merely tracking “engagement” through screen hits and mentions, librarians and others making digital projects can attempt to engage visitors in meaningful ways. The New York Public Libraries have begun allowing online users to assist with transcribing and marking items in the “What’s on the Menu?” project, for instance. Librarians can use digital technologies to extend scholarly communication practices to new audiences, as well as enhance current practices such as peer review in meaningful new ways often obscured by the dominant, paper-centered publishing practices.

    + +

    Basbanes and “Paper”

    + +

    The two most striking aspects of Basbanes’ talk were its capacious scope and its predilection to emphasize storytelling over analysis. Basbanes’ talk moved far beyond treating paper as a vehicle for scholarly communication, ranging into the technology’s affordances for modern sanitation (toilet paper) and warfare (prepared musket cartridges tripling the number of shots a gunner could shoot in a minute). While being quite flexible in terms of the range of applications of paper considered, Basbanes held to a relatively narrow definition of the substance: when the question of papyrus was raised, Basbanes cut the questioner off with an explanation that he was interested in the cellulose material and its spread, not the laminate that was geographically constrained to the Nile area. Despite their similar use, Basbanes clearly prefers paper due to its more global potential for production. Indeed, paper’s global nigh-ubiquity seems to have motivated his preferred title for the book, “Common Bond,” which he admitted is a “cute” pun on a particular grade of durable paper.

    + +

    This talk’s relevance for a digital libraries class is twofold. First, it helps establish the breadth of potential artifacts on paper beyond books, reinforcing the nuance of description that could be relevant when representing items digitally. Basbanes exemplifies the sort of scholar for whose work the descriptor “paper” would not be sufficient. While not relevant to every digital library project, his work serves as a reminder to consider the users and their needs when creating descriptions. Second, the scope of what he considers “paper” makes one think about what might be considered the “digital” for libraries and collections. What range of digital objects might future scholars wish to see preserved, and what are we already losing to the rapid obsolescence of operating systems, file types, or programs? How can we preserve the experience of working with digital programs and files for future scholars, when it’s often difficult to even preserve files that are meant to be outcomes, such as “stable” documents in proprietary formats?

    + +

    Commonalities

    + +

    Despite their very distinct subjects, these talks share a focus on the varied practices and applications that users bring to their respective materials. Fitzpatrick admitted to having a techno-utopian streak, yet recognized that tenure committees’ expectations around publication will continue to limit scholarly communication practices. Digital librarians would be wise to remember that we can help alter these practices by not only conscientiously creating projects, but also demonstrating the labor and scholarly choices that go into them. Basbanes showed the breadth of what can matter to a scholar, and digital librarians can certainly take guidance from the wide-lens scope of his inquiry when considering what to include when creating projects that focus on born-digital items.

    + + + + +
    + + + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/portfolio/index.html b/portfolio/index.html new file mode 100644 index 000000000..e417db0a1 --- /dev/null +++ b/portfolio/index.html @@ -0,0 +1,567 @@ + + + + + + +Portfolio — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

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

    Here are some of the more library-related things I’ve done. This is current as of 2015-10-10. My full cv is available here.

    + +

    Presentations and Talks

    + +

    Productive Interpretations: Encouraging Patron Agency Through Cultural Criticism, CAPAL 2016

    + +

    intro slide

    + + + +

    LIS Education and New Conceptions of Democracy, 2015 Symposium on LIS Education

    + + + + + + +

    Writing

    + +

    Publications

    + + + +

    Technical Reports

    + + + +

    Presentations

    + + + +

    Blog Posts Elsewhere

    + +

    Hack Library School

    + + + +

    ET2 Blog (the Government Information, Maps, and Microform Services Department at IU’s Herman B Wells Library)

    + + + +

    Digital Signage

    + + + + +
      +
    • “2014 Indiana State Elections” slideshow for the ET2 Digital Displays.
    • +
    + + + + +
      +
    • “Literary Maps” slideshow for the ET2 Digital Displays.
    • +
    + +

    Projects

    + +

    Raincross Underground

    + +

    Raincross Underground Babyhead Image

    + +

    Begun for my Digital Libraries class with John Walsh, Raincross Underground is an Omeka site with items from a Riverside, CA creative scene that existed during the early 2000s. It includes images, sounds, and TEI markup of songs from a band I was in.

    + +

    Bloomington City Directories Finding Guide

    + +

    Bloomington City Directories Finding Guide

    + +

    Making the Bloomington City Directories Finding Guide began with an inventory of the various directories held by the Herman B Wells Library. Then I had to decide the best way to organize and present this information to our patrons. Finally, I wrote the html code to inclue the guide on the website.

    + +

    Indiana Historical Maps Digital Collection

    + +

    IHMDC

    + +

    Although the work of digitizing this collection began before I arrived at the Government Documents, Maps, and Microform Services department, the Indiana Historical Maps Digital Collection project took the bulk of my first year there. A large part of my role as the Maps Graduate Assistant involved digitizing and adding maps to this collection, as well as determining, adding, and standardizing appropriate metadata like tags that relevant researchers would find useful throughout the collection.

    + + + + +
    + + + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/posts/index.html b/posts/index.html new file mode 100644 index 000000000..890a8dad3 --- /dev/null +++ b/posts/index.html @@ -0,0 +1,3842 @@ + + + + + + +Posts by Year — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + +
    + + + + + +
    + +

    Posts by Year

    + +

    Alternately, you can view:
    +Posts by Category +Posts by Tag +

    + + + + + + + + +
    +

    2023

    +
    + + + + + +
    +
    + +

    + + Obsidian Tasks patterns + + +

    + + +

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

    + + +

    How I use the Tasks plugin for Obsidian. +

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

    + + AcWriMo2023 + + +

    + + +

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

    + + +

    Here’s how I’m giving Academic Writing Month a go this year. +

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

    + + I’ve Been Using Obsidian + + +

    + + +

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

    + + +

    I’ve been using Obsidian. Both enthusiastically and reluctantly. +

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

    + + Light Mode in Progress + + +

    + + +

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

    + + +

    Today’s work on putting together a light mode. +

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

    + + New note on Snippets and VS Code + + +

    + + +

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

    + + +

    Type similar things often? Here are some snippets you can use in VS Code. +

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

    + + New note on Rhetorical Précis + + +

    + + +

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

    + + +

    Looking for a succinct note-taking format? Try a rhetorical précis! +

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

    + + New note on Jekyll Guides + + +

    + + +

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

    + + +

    Note linking to some useful Jekyll guides. +

    +
    +
    + + + + + + +
    + +
    + + +
    + Back to top ↑ +
    + +
    +

    2022

    +
    + + + + + +
    +
    + +

    + + New note on Mastodon Settings + + +

    + + +

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

    + + +

    Looking to understand some Mastodon settings? Here are my own settings. +

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

    + + New note on Mastodon iOS apps + + +

    + + +

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

    + + +

    Looking for iOS apps for Mastodon? Here’s a few I recommend. +

    +
    +
    + + + + + + +
    + +
    + + + + + + +
    + +
    + + + + + + +
    + +
    + + + + + + +
    + +
    + + +
    + Back to top ↑ +
    + +
    +

    2021

    +
    + + + + + +
    + +
    + + +
    + Back to top ↑ +
    + +
    +

    2020

    +
    + + + + + +
    +
    + +

    + + New note on the VS Code editor + + +

    + + +

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

    + + +

    Looking for a nice code or text editor? Here’s why I like VS Code. +

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

    + + August 2020 Monthly Signal Boost + + +

    + + +

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

    + + +

    Mindfulness with the Waking Up and Plum Village apps; Most excellent tunes from Sonic D and Autodidact +

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

    + + SIFT Links + + +

    + + +

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

    + + +

    Links related to a lightning talk for the 2020 MOSS Meetup about our switch from the CRAAP test to the SIFT moves. +

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

    + + July 2020 Monthly Signal Boost + + +

    + + +

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

    + + +

    Organizing Ideas Podcast; The Latino Card; Tricycle Magazine; etc. +

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

    + + Introducing Monthly Signal Boosts + + +

    + + +

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

    + + +

    Monthly signal boosts will be short reflections on what I’ve read, listened to, watch, etc. +

    +
    +
    + + + + + + +
    + +
    + + +
    + Back to top ↑ +
    + +
    +

    2018

    +
    + + + + + +
    + +
    + + +
    + Back to top ↑ +
    + +
    +

    2017

    +
    + + + + + +
    +
    + +

    + + WA 2017 Week 09: Badges, Type, BibTeX + + +

    + + +

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

    + + +

    Briefly linking to Emily Ford’s article about badges, a short reference about using type on the web, and getting going with a bibliography tool. +

    +
    +
    + + + + + + +
    + +
    + + +
    + Back to top ↑ +
    + +
    +

    2016

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

    + + WA 2016 Week 31: Design Things Galore + + +

    + + +

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

    + + +

    Design thinking in Idaho libraries, button templates from Librarian Design Share and Char Booth, and a few minor site font updates. +

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

    + + WA 2016 Week 17: Research Notebook is Go! + + +

    + + +

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

    + + +

    Much like with succulents, I’ve planted an offshoot of this blog to see whether it’ll take root. Open Humanities Research Notebooks—come and join the future™. +

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

    + + WA 2016 Week 12: DERAIL, Site Updates + + +

    + + +

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

    + + +

    DERAIL 2016 student forum at Simmons! Also site updates — recommended readings pages and deep links with Anchor.js. +

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

    + + WA 2016 Week 07: Tools for Thinking + + +

    + + +

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

    + + +

    Tools for Thinking (for information literacy instruction) and Tech Tools for Keeping Thoughts in Order (using Atom and its packages) +

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

    + + WA 2016 Week 04: Library Privacy + + +

    + + +

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

    + + +

    Library privacy session with ACLU Idaho’s Ritchie Eppink and Library Freedom Project’s Alison Macrina at Meridian Library District’s unBound technology lab. +

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

    + + WA 2016 Week 02: Giroux on Neutrality + + +

    + + +

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

    + + +

    A culture of positivism, distinguishing between objectivity and objectivism, hegemony, false neutrality, values—this article has all sorts of relevance for l...

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

    + + Weekly Whaaa…? + + +

    + + +

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

    + + +

    Why weekly? Why assemblage? Why Fluxus? And what’s that “sous les pavés, la plage” thing about? +

    +
    +
    + + +
    + Back to top ↑ +
    + +
    +

    2015

    +
    + + + + + +
    +
    + +

    + + critlib #feelings + + +

    + + +

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

    + + +

    Why do I #critlib? Because another librarianship is possible. +

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

    + + WA 2015 Week 48 Fister, Kurz, Vecchione + + +

    + + +

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

    + + +

    Unanticipated Costs of “Doing More with Less”; Be Yr Own Her@; Making It Known that Libraraies are Spaces for Making +

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

    + + WA 2015 Week 47 Schoofs and Battista + + +

    + + +

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

    + + +

    Articles from LOEX Quarterly (one by Schoofs, another by Battista) that look at learning beyond the library’s space. +

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

    + + WA 2015 Week 46 Massumi and North + + +

    + + +

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

    + + +

    Enthusiasm about Massumi putting Deleuze in a nutshell! Analogies between the pedagogy & structural place of Writing Centers & libraries! Jekyll on t...

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

    + + Weekly Assemblage 2015 Week 45 + + +

    + + +

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

    + + +

    Three links & lots of enthusiasm! Elmborg’s “Literacies Large and Small,” a Time Management mega post, & how STEM relates to the liberal arts. +

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

    + + Weekly Assemblage 2015 Week 44 + + +

    + + +

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

    + + +

    Halloween at CWI Library (Once Upon a Time); Readings I’m looking forward to; Taught my first library resources session. +

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

    + + Weekly Assemblage 2015 Week 43 + + +

    + + +

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

    + + +

    A #critlib chat on gender & leadership in LIS, plus some history links. +

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

    + + Weekly Assemblage 2015 Week 42 + + +

    + + +

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

    + + +

    Live! Real! Humans! (in the Classroom); Code Camps, the “Californian Ideology,” & Higher Ed’s Purpose; Open Access & “The Library of Forking Paths.” +

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

    + + Weekly Assemblage 2015 Week 41 + + +

    + + +

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

    + + +

    Talking about librarianship values: objectivity as a value and valuing inclusivity enough to work toward it in earnest. And again—sorry, Eduardo. +

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

    + + Weekly Assemblage 2015 Week 40 + + +

    + + +

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

    + + +

    Starting at the College of Western Idaho & going to the Idaho Library Association 2015 Annual Conference! +

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

    + + Weekly Assemblage 2015 Week 39 + + +

    + + +

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

    + + +

    Getting library cards and appreciating some unexpected aspects of Maria Accardi’s Feminist Pedagogy for Library Instruction. +

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

    + + Weekly Assemblage 2015 Week 38 + + +

    + + +

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

    + + +

    Driving from Bloomington, Indiana to Boise, Idaho; Luciano Floridi’s Information: A Very Short Introduction. +

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

    + + Weekly Assemblage 2015 Week 37 + + +

    + + +

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

    + + +

    A #critlib chat on information & migrant populations; threats to the Tor exit node in Kilton Public Library; CFP for papers on whiteness in LIS; study on...

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

    + + Weekly Assemblage 2015 Week 36 + + +

    + + +

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

    + + +

    Reflections on the second #radlibchat and a Library Freedom Presentation by Alison Macrina. +

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

    + + All Hail Cloud Storage + + +

    + + +

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

    + + +

    Dropbox has both saved me from computer problems and helped me work more ubiquitously, so I sang the praises of it and other cloud storage at Hack Library Sc...

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

    + + Critical Hot Potato! aka #Rhizo15 Week Four + + +

    + + +

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

    + + +

    Reflecting on #critlib morphs into #critpotato for my much-delayed Week Four of #rhizo15 post, examining how online learning operates. +

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

    + + Presentation Alternatives: Reveal.js + + +

    + + +

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

    + + +

    Are you looking for a good alternative to PowerPoint or Keynotes? Here’s a Hack Library School post about an excellent free & open source one! +

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

    + + #Rhizo15 Week Three: "Content is People" + + +

    + + +

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

    + + +

    For Week Three of #rhizo15, I trace a few thoughts on content vs discontents or reification and the observable outcomes of human actions. +

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

    + + Everything Counts in Affective Amounts + + +

    + + +

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

    + + +

    Week Two of #rhizo15—How we might count the affective aspects of learning? Also, what potential does Git give us for making open humanities notebooks? +

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

    + + Hack Quirk Your Presentations + + +

    + + +

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

    + + +

    I wrote for Hack Library School about using quirky results or affordances to make your instruction sessions more engaging. +

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

    + + Learning Subjectives + + +

    + + +

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

    + + +

    For Week One of #rhizo15, I write about my predilection for research processes over writing outcomes & whether library “neutrality” thwarts supportive de...

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

    + + Wojnarowicz on a Sphere + + +

    + + +

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

    + + +

    Still under construction, this post will be about my process of making a map of artist David Wojnarowicz’s gallery exhibits for the NOAA Science on a Sphere. +

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

    + + #critlib Makerspaces + + +

    + + +

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

    + + +

    I write about moderating a #critlib Twitter chat on the constructivist potentials and neoliberal downsides of makerspaces, as well as briefly describe the mo...

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

    + + Freire and Critical Librarianship + + +

    + + +

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

    + + +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship. +

    +
    +
    + + + + + + +
    + +
    + + +
    + Back to top ↑ +
    + +
    +

    2014

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

    + + Software Carpentry Workshop Reflections + + +

    + + +

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

    + + +

    Although aimed at scientists, Software Carpentry’s workshops offer great learning experience for librarians, digital humanities folks, and anyone looking to ...

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

    + + Review of Online Archive of California + + +

    + + +

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

    + + +

    The Online Archive of California lies somewhere between a finding aid and a digital library—and is a huge boon to researchers that would be worth emulating e...

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

    + + Bigfoot Spotting and Other Jekyll Adventures + + +

    + + +

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

    + + +

    A post where I describe trying—and thus far, failing—to use Bigfoot.js to make footnotes more engaging in a Jekyll/GitHub Pages blog. I’ll revisit this soon ...

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

    + + New Directions in Information Fluency + + +

    + + +

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

    + + +

    Brief reflections on a talk about bringing digital humanities to the reference desk, which I co-presented with Katherine Ahnberg at the New Directions in Inf...

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

    + + Test One + + +

    + + +

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

    + + +

    Here’s a stellar ditty from Warp™ records that deserves being listened to with headphones or a subwoofer. +

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

    + + New Site + + +

    + + +

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

    + + +

    A Depeche Mode reference is more interesting than Hello World, isn’t it? +

    +
    +
    + + +
    + Back to top ↑ +
    + +
    +
    +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/quick-thoughts-on-method.html b/quick-thoughts-on-method.html new file mode 100644 index 000000000..7c6fd6837 --- /dev/null +++ b/quick-thoughts-on-method.html @@ -0,0 +1,670 @@ + + + + + + +Quick Thoughts on Method & Knowledge Practices in Arts & Humanities — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + +

    Earlier today I saw a few #critlib threads swirling around on Twitter—here’s one and here’s another. The ones that caught my eyes mostly had to do with how open #critlib twitter chats & their participants seem to critique or criticism, the extent to which critical theory has to do with social justice, and what critical theory does or doesn’t include.

    + +

    That’s a lot to think about, particularly on the first truly summery Friday afternoon of the year. Good thing we’ve got a “critiquing #critlib from within” coming up on June 30th, right?

    + +

    Another person’s comment mused something along the lines of “What’s interesting to me [as someone with a science background] is that I thought people in the Arts were better prepared to talk about critical theory, but it seems like that might not be the case.” I suspect that thinker might have removed it out of fear of being seen as snarky, but I believe they were very much onto something.1

    + +

    So, all this tweeting has me thinking about how we teach method in (parts of) the humanities.

    + +

    In my experience, I encountered many theories in my literature & film courses but this was almost always to apply or debate them, not discuss their genealogies.2 Even though we’d discuss or situate each theory’s history briefly, theories chiefly were lenses to apply, not subjects to study of themselves.

    + +

    My memories of undergrad are somewhat clouded by having taken MA courses with many of the same faculty, but it feels like my undergrad experience was pretty theory-heavy (perhaps due to my own interest in it). Oddly enough, I don’t remember having a proper “methods” course.3 Later, as a PhD student, I enjoyed the opportunity to TA for a “senior seminar” on various critical (Marxist, feminist, postcolonial, etc) theories for comparative literature majors, as well as TA for a couple “writing on art” courses for art history & studio arts students. But even though these courses did excellent work of exposing students to theory & interpretive methods, I believe their final papers were to apply multiple theories to various literary or visual texts, not to evaluate various methods of making truth claims. Having learned more about pedagogy, I think it’s seriously worth considering the results of these decisions.4

    + +

    I think this leads humanities majors—with the likely exceptions of history & philosophy, who I believe focus on method earlier—to do two main things.

    + +

    First, I suspect that many humanities degree holders feel quite uncomfortable discussing “critical theory” as an entity, and will equally avoid situating various theories’ relationships to each other. We know in our bones that they’re complicated, contested, & possibly even interlocking, intersectional, or some kinda interpenetrating—but at the undergraduate level we have never been tasked to do much more than select among them & apply them to texts. Certainly we haven’t been asked to consider at length or trace the evolution of different strains of thought as they became genealogies of knowledge spanning multiple years, schools of thought, contested keywords, etc., etc. This makes it difficult to feel equipped to appraise something as nebulous, sprawling, and challenging a beast as “critical theory”/ “Critical Theory”/ “are you talking the one with capital letters? does it matter?” later on, even though we recall having been handed appropriate tools for thorny considerations of age, class, complexion, dis/ability, ethnicity, gender, nationality, race, region, sexuality, et. al. as well as many of their possible permutations and combinations.

    + +

    Second, more unsettlingly, I fear that we rarely feel equipped to discuss knowledges, practices, truth claims, ontology, epistemology, or similar sorts of method-focused concerns. This might well be why so many humanities & liberal arts graduates emerge with enormous facility with argumentation, empathy, historical specificity, etc., but simultaneously stumble when asked to give a succinct answer to explain their “reason” for choosing a humanities major or what it offers them throughout their lives. Constructivist pedagogy suggests that we learn by doing. I believe that most of us have applied critical theory routinely but in a somewhat piecemeal fashion and never really evaluated their various ways of making and practicing knowledge.

    + +

    Since most readers will be coming to this with a background in library & information science, critical pedagogy, or perhaps digital humanities, I’d love to hear your experience of your own undergraduate coursework with regard to method, or of how you teach method to undergraduates if you do so in any capacity. Does this Friday evening musing ring true with you? Is it different in social sciences or science?

    + +

    What might we do to help foster a bit more critical understanding of method in arts & humanities courses? Does it seem like social justice, critical theory, and/or critical information literacy can be woven into discussions of method for arts & humanities courses?

    + +

    Until I sort out whether/how to put comments on this blog, I guess the best way to have a conversation with me would be through Twitter if you use it. Perhaps you might write a post of your own & link me to it? Maybe you’ll join in the critiquing #critlib from within conversation in a few weeks?

    +
    +
      +
    1. +

      Seriously, thanks, Twitter friend, for spurring me to think about this more! 

      +
    2. +
    3. +

      In case you’re morbidly curious, I ended up with an English major, a film & media studies minor, and a “philosophy” minor that really was primarily focused on 20th century critical theory/continental thought. Among other things, this what happens when you (a) start out wanting to do philosophy but then start to wonder why these are the only courses that don’t approach the diversity present in the syllabi, faculty, and classrooms of your other arts & humanities courses and (b) have the historical privilege of relatively affordable in-state tuition at an amazing, open-minded state institution in the 1990s. I seriously doubt I’d financially or emotionally afford to wind my way through what’s effectively an expanded cultural studies degree were I attending undergraduate anywhere with today’s tuition rates. 

      +
    4. +
    5. +

      This may have changed for later students when my English department became more regimented. Among other things, I vaguely remember them instituting required prerequisites for upper- vs lower-division courses rather than treating them more as fluid guidelines. 

      +
    6. +
    7. +

      Iowa State University has a page I’ve found very useful when I want to revisit Bloom’s Taxonomy of Educational Objectives, which is a classic when discussing educational tasks like applying or evaluating. 

      +
    8. +
    +
    + + + + +
    + + + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/reading/index.html b/reading/index.html new file mode 100644 index 000000000..b02096217 --- /dev/null +++ b/reading/index.html @@ -0,0 +1,533 @@ + + + + + + +Reading — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

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

    I’ve occasionally kept track of what I’m reading on BookWyrm, Goodreads, or similar sites.

    + +

    As an ongoing experiment with centralizing things to this site, I’m going to try doing so here as well/instead. I often read multiple books and articules in parallel, so I plan to annotate my progress here.

    + +

    I plan to add links to reading notes in my digital garden once I’m done, as a type of review.

    + +

    Currently Reading

    + + + + + + + +

    2023

    + + + + + + + +
    + + + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    +
    + + +
    +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/recommended-reading/index.html b/recommended-reading/index.html new file mode 100644 index 000000000..5c25a99fe --- /dev/null +++ b/recommended-reading/index.html @@ -0,0 +1,591 @@ + + + + + + +Recommended Reading — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

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

    :construction: :construction: :construction:
    +Just like our world and societies, these “recommended readings” pages remain continually under construction.
    +:construction: :construction: :construction:

    + +

    I’m inspired by April Hathcock’s and Jess Schomberg’s lists and want to share something similar. I plan to have a range of things here, eventually including links to my own posts that deal with cultural studies & critical theory, particularly as it pertains to LIS. I’m also planning to organize and annotate these recommendations more along the way.

    + +

    The below certainly isn’t my attempt at an “intro to #critlib” or “intro to critical theory”—these are just readings that I profoundly appreciate and recommend to anyone interested. My motivation is that I’m working toward having a quick answer to what I mean by “cultural studies,” and these are some of the readings that are helping me develop that kind of elevator speech about what critical theory means to me.

    + +

    I’ll start working on a more “intro to #critlib” section soon enough and some of these will reappear there.

    + +

    More Detailed Lists

    + + + +

    Books

    + +

    More towards Cultural Studies / Critical Theory

    + + + +

    More towards Critical Pedagogy / Critical Information Literacy

    + + + +

    Articles

    + +

    More towards Cultural Studies / Critical Theory

    + + + +

    On top of being about disco and downtown NYC art music, this article made me stop judging Deleuze & Guattari based on their fanboys and instead appreciate how assemblage theory can help us avoid adopting Great Men approaches to history. Lawrence also writes superbly, even when harnessing academic language. And he’s considerate enough to have put this in Liminalities: A Journal of Performance Studies, an open access, peer-reviewed journal.

    + + + +

    Jonathan Sterne writes, thinks, and speaks wonderfully. Check out his repository as well as his blog. You’ll find some other great stuff like “Keyword: Journal”, “Pedagogy of the Job Market”, and “Communication as Techné”, not to mention an entire page stuffed full of advice for those venturing into academe. Can you imagine a world where all scholars and thinkers were routinely this generous?

    + + + +

    It’s unfortunate that this reading isn’t more widely accessible—although he does touch on a lot of similar topics in a few of the many articles he has on Academia.edu, which I feel vaguely dirty even linking to since it’s far from a substitute for an actual institutional repository.

    + +

    Across this and some similar essays (“Wandering Audiences, Nomadic Critics,” “Cultural Studies and/in New Worlds,” “The Formations of Cultural Studies: An American in Birmingham,” “On the Political Responsibilities of Cultural Studies,” & “History, Politics, and Postmodernism: Stuart Hall and cultural studies”)1 Grossberg does a stellar job of showing how cultural studies has evolved from a group of scholars primarily from working class backgrounds interested in adult education & labor concerns to a more intentionally decolonial, feminist, and queer undertaking. He does a great job of explaining Stuart Hall, Angela McRobbie, and other Cultural Studies touchstones, as well as showing how the cultural studies approach that he advocates for focuses on a materialist study of the effects of practices and how they are articulated, an approach that is simultaneously both anti-essentialist and not relativistic, basing a claim’s truthfulness on its ability to give the thinker purchase on effects in the world.

    + +

    More towards Critical Pedagogy / Critical Information Literacy

    + + + +

    Blog Posts

    + + + +

    Blog Roll

    + +

    Further Blog Roll and Other Links

    +
    +
      +
    1. +

      I also really like Grossberg’s “The Ideology of Communication: Post-Structuralism and the Limits of Communication,” which is on that non-IR site. It’s definitely not an introductory reading, but it’s a good one. 

      +
    2. +
    +
    + + + + +
    + + + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    +
    + + +
    +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/recommended-readings-critical-librarianship/index.html b/recommended-readings-critical-librarianship/index.html new file mode 100644 index 000000000..3b1d59931 --- /dev/null +++ b/recommended-readings-critical-librarianship/index.html @@ -0,0 +1,486 @@ + + + + + + +Recommended Readings for Critical Librarianship — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

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

    Within librarianship, I mostly do instruction, outreach, and reference. As these are my most local and constant contexts, these practices inflect how I think of librarianship. It’s unsurprising, therefore, that most of these articles have to do with those things—but this connection certainly doesn’t mean that I think critical librarianship only exists within these contexts!

    + +

    I’ll link to things beyond these contexts as well, when I read ones that excite me. Of course, I’d love for you to write a list like this that focuses on your own approaches to librarianship.

    + +

    Critical Pedagogy & Critical Information Literacy

    + +

    Books

    + + + +

    Articles

    + + + +

    Critical Librarianship Blog Posts & Blogs

    + + + + +
    + +
    + + + + + + + + + + +
    Created:
    + + +
    Updated:
    + +
    + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/recommended-readings-critical-theory/index.html b/recommended-readings-critical-theory/index.html new file mode 100644 index 000000000..12f1dee68 --- /dev/null +++ b/recommended-readings-critical-theory/index.html @@ -0,0 +1,532 @@ + + + + + + +Recommended Readings for Critical Theories — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

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

    Of all the various types of critical theory, I identify most closely with cultural studies.

    + +

    Some of My Favorite Books on Critical Theories

    + + + +

    Some of My Favorite Articles on Critical Theories

    + + + +

    On top of being about disco and downtown NYC art music, this article made me stop judging Deleuze & Guattari based on their fanboys and instead appreciate how assemblage theory can help us avoid adopting Great Men approaches to history. Lawrence also writes superbly, even when harnessing academic language. And he’s considerate enough to have put this in Liminalities: A Journal of Performance Studies, an open access, peer-reviewed journal.

    + + + +

    Jonathan Sterne writes, thinks, and speaks wonderfully. Check out his repository as well as his blog. You’ll find some other great stuff like “Keyword: Journal”, “Pedagogy of the Job Market”, and “Communication as Techné”, not to mention an entire page stuffed full of advice for those venturing into academe. Can you imagine a world where all scholars and thinkers were routinely this generous?

    + + + +

    It’s unfortunate that this reading isn’t more widely accessible—although he does touch on a lot of similar topics in a few of the many articles he has on Academia.edu, which I feel vaguely dirty even linking to since it’s far from a substitute for an actual institutional repository.

    + +

    Across this and some similar essays (“Wandering Audiences, Nomadic Critics,” “Cultural Studies and/in New Worlds,” “The Formations of Cultural Studies: An American in Birmingham,” “On the Political Responsibilities of Cultural Studies,” & “History, Politics, and Postmodernism: Stuart Hall and cultural studies”)1 Grossberg does a stellar job of showing how cultural studies has evolved from a group of scholars primarily from working class backgrounds interested in adult education & labor concerns to a more intentionally decolonial, feminist, and queer undertaking. He does a great job of explaining Stuart Hall, Angela McRobbie, and other Cultural Studies touchstones, as well as showing how the cultural studies approach that he advocates for focuses on a materialist study of the effects of practices and how they are articulated, an approach that is simultaneously both anti-essentialist and not relativistic, basing a claim’s truthfulness on its ability to give the thinker purchase on effects in the world.

    + +
    +
      +
    1. +

      I also really like Grossberg’s “The Ideology of Communication: Post-Structuralism and the Limits of Communication,” which is on that non-IR site. It’s definitely not an introductory reading, but it’s a good one. 

      +
    2. +
    +
    + + + + +
    + +
    + + + + + + + + + + +
    Created:
    + + +
    Updated:
    + +
    + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/reveal-js-hack-library-school.html b/reveal-js-hack-library-school.html new file mode 100644 index 000000000..5b6bbf3a4 --- /dev/null +++ b/reveal-js-hack-library-school.html @@ -0,0 +1,694 @@ + + + + + + +Presentation Alternatives: Reveal.js — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + +

    Here’s a post I wrote for Hack Library School talking about my experience with the Reveal.js JavaScript presentation framework. Not only does it hew to my goal of choosing open-source tools over proprietary formats whenever feasible, its functionality and inherent ability to make presentations shareable on the web make it vastly preferable to tools like PowerPoint or Keynote.

    + +

    As librarians, academics, archivists, and/or instructors, we should consider the effects of the formats we choose. How durable are they? How accessible are they? Whose interests do they serve? Whether you frame this as format information creation as a process”, something closer to “format as culture,” or even “we jam econo,” please be deliberate.

    + +

    The post at Hack Library School sits within a series introducing and explaining alternatives to PowerPoint, so it’s not quite a how-to sort of post. If you’d like pointers, please do feel free to get in touch via Twitter or when I add them—which I expect will be soon not happen until GitHub Pages adds an appropriate plugin—the Jekyll Static Comments system that I’m slowly working out.1

    + +

    edits on 2016-04-04 & 2016-04-05:

    + +

    I found a great tutorial today: Reveal.js for Beginners. If you’re looking at implementing this on your own site, I’d highly recommend starting there.

    + +

    Also, I’d like to elaborate a little on the multiple, intersecting types of accessibility I think this type of mobile, audience-member-controllable slide presentations promotes:

    + +
      +
    • mobile device +
        +
      • economic
      • +
      +
    • +
    • people with disabilities +
        +
      • low-vision / blind (i.e. users of screen reader technology)
      • +
      • people with attention disabilities or cognitive disabilities (ADHD, dyslexia, executive dysfunction resulting from a wide variety of causes, learning disabilities, etc.)
      • +
      +
    • +
    • pedagogical accessibility
    • +
    + +

    Many of these overlap, of course. For instance, it’s quite common for economically underprivileged people to own or have access to a mobile device but not a laptop. We see this continually at the community college where I work! We also work with—and indeed, are ourselves—students, instructors, librarians, and staff with what I’m calling attention or cognitive disabilities. (I’m lumping those together not because they have the same root causes, but because they all seem to be best addressed by providing a way for the person to control how much time they spend engaging with something.)

    + +

    These attention disabilities bring us to pedagogical accessibility. How many times have you wanted to write down a link or reference that was the last thing on a slide, but the speaker advances it just a few moments too quickly? How many times do you wish you could go back to see a term or definition introduced earlier in the talk, but couldn’t?

    + +

    Giving your audience the ability to engage with your slides as you talk effectively aides your audience in becoming actual interlocutors, able to engage with your ideas on their terms & at their speeds. Why choose to ensnare them within your own timing? This slide framework promotes the attitude of generosity and loving kindness that I associate with bell hooks’ writings.2

    + +

    All that said, one still needs to add alt descriptions to images in Reveal.js talks! Since I initially made my current information literacy slides for my position interview, which happened as I was still learning how to make slides with this javascript framework, I neglected to do this. I have just gone back and fixed that now. I’ll have to find someone who uses screen readers to see how accessible they feel these slides are now.

    + +

    As for Reveal.js itself, the issues for this framework show that at least one of the people contributing to the project is Marcy Sutton, who has apparently helped with Girl Develop It’s accessibility slides. Here’s her page of web accessibility resources. I’ll be going through these soon to continue learning about how to make web resources more accessible for people with visual disabilities.

    + +

    Or as I said in today’s #critlib chat, #critlib is a process.

    + + + + +

    If there’s one “should” statement I feel comfortable making, it’s that we should continually try to do better, collectively and individually. Part of doing better involves, to the degree individually possible, being willing to point out our own mistakes and how we’re improving what we’ve done.

    + +

    Or in the immortal words of Bill S. Preston, Esq., “Be Excellent to Each Other.”

    + +

    Bill and Ted saying Be Excellent to Each Other and Party On, Dudes

    +
    +
      +
    1. +

      Edit on 2016-04-05: At the moment, it’s unlikely I’ll be adding a Jekyll Static Comments plugin. I prefer this type of system over using Disqus since this is based on emails, and therefore people wouldn’t have to sign up for yet another web service. However, that means I’d have to work out per-post emails and then dial in a spam filter. Also, it’s not one of the few plug-ins GitHub Pages supports. That means that I have to build my site locally, then sync it to GitHub’s servers. I’d never be able to update my site from my phone, which I have done on occasion and want to continue being able to do. So until (a) GitHub allows a version of email-based commenting to work on GitHub Pages, (b) I learn enough and/or choose to move my site to GitLibs or Heroku, or (c) I actually get multiple people reaching out on Twitter or elsewhere saying that they’d want to leave comments, I’m deep-freezing this task in carbonite. 

      +
    2. +
    3. +

      It’s late as I write this and I’ve got a few of her works muddled together. I’ve recently read most of Teaching to Transgress, a conversation between her and Thich Nhat Hanh, and an interview with her at Tricycle, so I’m not sure what to cite for this notion at the moment. If I haven’t revised this by firming up a reference, please reach out to me on Twitter and I’ll try to figure it out or point you in a good direction. 

      +
    4. +
    +
    + + + + +
    + + + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/review-of-online-archive-of-california.html b/review-of-online-archive-of-california.html new file mode 100644 index 000000000..b9a412f69 --- /dev/null +++ b/review-of-online-archive-of-california.html @@ -0,0 +1,687 @@ + + + + + + +Review of Online Archive of California — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + +

    This post was originally an assignment for John Walsh’s “Z652 Digital Libraries” course at IU-Bloomington.

    + +

    Banner image of Online Archive of California's logo and search bar.

    + +

    A fantastic clearing house of information about Californian collections, the Online Archive of California serves as a centralized set of links to and descriptions of an enormous number of collections from various archives, historical societies, libraries, museums, and special collections in California, including each campus of the University of California. According to the OAC’s about page, this makes for over 200 contributing institutions, more than 20,000 online collection guides, and more than 220,000 digital images and documents.1 Administered by the Digital Special Collections program of University of California’s California Digital Library (CDL), the Collection aims to increase the ease with which collections held throughout a variety of Californian institutions can be found by researchers. In addition to increasing this “findability,” the Archive benefits the involved member institutions by giving access to a variety of tools, services, and training from the OAC, as well as by expanding grant opportunities as a result of the partnership with the CDL.

    + +

    As a project, the OAC goes back to a prototype finding aid standard made in 1993 at the UC Berkeley Libraries. In 1995, several University of California libraries began “UC-EAD” to test Encoded Archival Description to integrate access to collections information across the UC campuses. The project outgrew its initial UC cross-campus scope and was renamed the Online Archive of California in 1998 when it began including information about collections housed elsewhere.2 Due to its consortial nature, it’s difficult to determine when the resources available through the OAC were last available. The site also does not provide an easily-found list of when collections were added to its list, but for what it is worth, the CDL’s page about the OAC was last updated on 13 December, 2013.3 The CDL Digital Special Collections administers the OAC, but its component descriptions and representative digital files come from the member institutions.

    + +

    This Digital Special Collections team includes six people: a “Director,” “Technical Lead,” “Program Coordinator,” “Contributor Support Specialist,” “Programmer Analyst,” and “Data Consultant.” It appears that five work in Oakland and one in San Diego. Although the team does not list every member’s background, their previous experience appears to vary in precisely the way that seems common to digital humanities/digital libraries work: Catherine Mitchell, the Director, has a Ph.D. in English Literature from UC Berkeley and was previously the Web Director at the Commonwealth Club of San Francisco; Brian Tingle, the Technical Lead, received a B.S. in Ecology, Behavior, & Evolution from UC San Diego and has worked from the UC Libraries since 1996; and Adrian Turner, the Data Consultant, earned an M.L.I.S. from UCLA and an M.A. from UC Santa Cruz and has worked as an archivist and manuscripts processor at UC Irvine Special Collections and Archives, among other places.4 The OAC has a broad focus, taking any collection held by a Californian archive, college, historical society, library, museum, special collection, or university as its subject. As shown in the image below, content in the OAC is browsable by institution, by collection, and by location on a map—the last of which must be particularly useful to visiting researchers unfamiliar with the size and geography of California.

    + +

    OAC browse functions—especially geography!

    + +

    Not surprisingly, considering its history as a means of testing the Encoded Archival Description (EAD) metadata standard, the OAC uses EAD extensively. As of July 2008, the site allows for searches across MARC records and EAD through a single search system.5 According to its technical information page, the Metadata Encoding and Transmission Standard (METS) and the Archival Resource Key (ARK) schema are also used for the content in the repository shared by the OAC and Calisphere.6 The Archive makes its metadata records available for other aggregators through OAI-PMH.7 The project began in part to test EAD, but the MARC records (specifically MARC21) that were later integrated likely preceded the OAC. It’s unclear how these records were converted to digital format when and if it was necessary.

    + +

    According to the “Calisphere and OAC Technical Information” page, CDL developed a platform based on XML and XSLT for the repository at the heart of the OAC and Calisphere projects. This platform is packaged as the eXtensible Text Framework, or XTF, containing Java Servlets, Lucene indexing technology, and XSLT stylesheets. Lucene, made by Apache, seems to be the only off-the-shelf software package used by the OAC, with the bulk instead being programmed in-house—or else customized, as the OAC has done with LuraTech’s Image Content Server. The images used in the OAC are JPG-2000 files, derived from TIFF images. The OAC employs XTF for search and delivery of TEI, PDF, or imaged text-based digital objects, as well as EAD collection guides and MARC records. CDL’s Guidelines for Digital Objects details the OAC’s use of files.8 Due to the range of object types, there is a wide range of format choice: JPG, JPG-2000, PNG, TIFF, HTML, XML, PDF/A, UTF-8, ASCII, AIFF, WAVE, GZIP, and ZIP files are the listed preferred format choices. QuickTime VR and GIF are also mentioned, but they are not on the list of “preferred formats” stated above. If a production TIFF is submitted, it will be used for to derive the displayed JGP-2000 image and then deleted rather than used as a preservation format.

    + +

    The OAC aims to aid “research-oriented users who want to go beyond what is available online and locate the actual, physical item,” whereas its sibling Calisphere draws from the same digital content to serve a website targeting “users whose primary interest is to view digitized images and documents.”9 Searches can be performed from a single bar, which then allows limiters to be placed on the results. Results can be ordered by relevance and title, with limits available by institution, by date (to the decade), and whether online items are available (i.e. images or text beyond the OAC’s description). The OAC seems to place an equal emphasis on browsing, for its landing page highlights that the Archive can be browsed by institution, collection, and map. Not only are these functions accessible from a menu bar across the top, but the visitor will immediately recognize these capabilities because they present themselves in three columns, already populated with information (see image below).

    + +

    Image of OAC's landing page with three columns of browsing functions.

    + +

    In a section of its “Help” page, the OAC clarifies what users may do with materials they find through the Archive.10 The OAC alerts users to the fact that copyright may pertain to the Archive’s materials and that it neither owns nor houses any of the listed materials. The OAC then refers users to the institution housing the relevant collection, noting that each collection guide contains a link to contact information at the top.

    + +

    While it is not an exclusively digital library, as it does not contain digital versions of everything it mentions or indexes, the OAC provides a profoundly useful service in offering a centralized access point to descriptions of collections throughout California. Beyond the time researchers save, this centralized repository vastly increases the likelihood that holdings in less prominent venues will be used by researchers from outside those locales. My brother, a journalist currently writing a book on the history of Malibu, had to rely on Google searching in order to determine that Pepperdine University holds the main archives he has consulted thus far. When I sent him a link to the OAC, he seemed ecstatic, despite the fact that he has already submitted his initial drafts to his publisher. Although he and I both lived in California for more than 15 years, we had never heard of this resource, and he now lives in Brooklyn. As a distant researcher whose knowledge of Californian collections will be heavily mediated by online resources, this Archive already offers excellent utility, should he require further research for future edits or subsequence projects.

    + +
    +
      +
    1. +

      “About OAC.” Online Archive of California. California Digital Library. Web. 19 Sept. 2014. 

      +
    2. +
    3. +

      Rinehart, Richard. “Museums and the Online Archive of California.” First Monday 7.5: 6 May 2002. Web. 18 Sept. 2014. 

      +
    4. +
    5. +

      “Online Archive of California.” California Digital Library. Web. 19 Sept 2014. 

      +
    6. +
    7. +

      “Digital Special Collections.”. California Digital Library. 13 Dec. 2013. Web. 19 Sept. 2014. 

      +
    8. +
    9. +

      “OAC History.” California Digital Library. 20 May 2014. Web. 19 Sept. 2014. 

      +
    10. +
    11. +

      “Calisphere and OAC Technical Information.” California Digital Library. 22 Nov. 2013. Web. 19 Sept. 2014. 

      +
    12. +
    13. +

      “OAI-PMH Data Service.” California Digital Library. 20 Aug. 2013. Web. 19 Sept. 2014. 

      +
    14. +
    15. +

      “CDL Guidelines for Digital Objects.” California Digital Library. Aug. 2011. Web. 19 Sept. 2014. 

      +
    16. +
    17. +

      “Calisphere.” California Digital Library. 22 Nov. 2013. Web. 19 Sept. 2014. 

      +
    18. +
    19. +

      “Frequently Asked Questions.” California Digital Library. Web. 19 Sept. 2014. 

      +
    20. +
    +
    + + + + +
    + + + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/rhizo15-week-three.html b/rhizo15-week-three.html new file mode 100644 index 000000000..9c5e9ce5f --- /dev/null +++ b/rhizo15-week-three.html @@ -0,0 +1,650 @@ + + + + + + +#Rhizo15 Week Three: "Content is People" — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + +

    This post is for Week Three of #rhizo15: “The Myth of Content.” Even though I’m writing this during Week Five, I’m trying to put my thoughts out a little quicker than usual in this post, in keeping with my post from Week One.

    + +

    For Week Three, Dave asked:

    + +
    +

    So what happens when we peek under the word ‘content’ to see what lives there? What does it mean for a course to ‘contain’ information? What choices are being made… what power is being used? +or +Content is people. Discuss.

    +
    + +

    I’d say that in order to avoid routinely reifying “content,” the healthiest approach is to assume that content is always just what a particular system can capture. Most of what can be “contained” in a course are documents or bibliographies, and the beauty of a course is that participants then interrogate, alter, and perhaps incorporate aspects of what they think as a result of meeting these documents into their own ways of knowing. Perhaps they change their ways of knowing?

    + +

    An adjacent question would be what course management software can “contain,” and what we think we’re doing when we observe its use. Some of the newer systems allow instructors to see how often students interact with different portions of the course content within the management system. What I worry about is how often professors might overlook this last clause—within the management system—and forget that students might have their own ways of managing their information.

    + +

    Dropbox, email, iBooks, Box, Spider Oak, Google Drive/Google Keep/Google Whatever They’ve Recently Introduced and Will Likely Sunset in a Few Years—observant knowledge management professionals know that users will continue to rely on the tools that are most comfortable to them and already most well-integrated into their lives, not the “official” ones that best serve administrative purposes.

    + +

    To chase a tangential set of thoughts, this week’s prompt reminds me of Barbara Fister’s excellent article “Teaching the Rhetorical Dimensions of Research”, in which she discusses the fact that “most of our systems don’t retrieve information, they retrieve texts.” What we hope as instructors or (critical) information literacy librarians isn’t for students to magically be able to find information as a thing divorced from human processes (of rhetoric, persuasion, interpretation, etc.), but instead for students to be able to perform actions that showcase critical thinking skills and increasingly sophisticated approaches to the information that lies in these documents. How did these documents come about? What structures might inhere in them, perhaps hidden even to the authors? How might these things distort the information or require us to reconsider how we contextualize it within other relevant structures?

    + +

    So yes, Virginia Dave, content is people. More specifically, course content is the outcome of people’s actions, the inadequate ways that these actions can be captured by and appear within processes of composition, behavior tracking in learning management software systems, or planning of a course syllabus. Extending good faith toward our students and patrons will help us understand that there might be (desired) behaviors beyond what we can observe through learning management systems, website analytics, even assignments and term papers. Continually attempting to challenge reification—attending to the discontents that might accompany the observable content—should help us to take a more critical, potentially Freirean approach to learning and education.

    + + + + +
    + + + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/robots.txt b/robots.txt new file mode 100644 index 000000000..cd19e3506 --- /dev/null +++ b/robots.txt @@ -0,0 +1,4 @@ +sitemap: https://ryanpatrickrandall.com/sitemap.xml + +User-agent: GPTBot +Disallow: / \ No newline at end of file diff --git a/safari-pinned-tab.svg b/safari-pinned-tab.svg new file mode 100644 index 000000000..4511e8d89 --- /dev/null +++ b/safari-pinned-tab.svg @@ -0,0 +1,15 @@ + + + + +Created by potrace 1.11, written by Peter Selinger 2001-2013 + + + + + diff --git a/sandbox/index.html b/sandbox/index.html new file mode 100644 index 000000000..9da2921ab --- /dev/null +++ b/sandbox/index.html @@ -0,0 +1,349 @@ + + + + + + +Sandbox — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + +
    + + + + + +
    + +
    +

    + +

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

    You’ve entered a workshop space. Remember, safety first!

    + +

    doc brown wearing goggles and holding jumper cables

    + +
    +

    A strange game. The only winning move is not to play.

    +
    + +

    Testing Placeholder Text for Form Fields

    + +
      +
    • testing italic fonts as well
    • +
    • testing bold fonts as well
    • +
    • testing italic bold fonts for sure
    • +
    + +

    Placeholder Test

    + +

    + +

    + +

    The above text uses the placeholder html attribute.
    +It offers a suggestion or example that will disappear when other text is entered.

    + +

    Value Test

    + +

    + +

    + +

    The above text uses the value html attribute.
    +It prepopulates the field with that text.

    + + + + +
    + +
    + + + + + + + + + + +
    Created:
    + + +
    Updated:
    + +
    + + + + +
    + + +
    + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/sift-links.html b/sift-links.html new file mode 100644 index 000000000..2e786cda0 --- /dev/null +++ b/sift-links.html @@ -0,0 +1,662 @@ + + + + + + +SIFT Links — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + + + +

    Here are some links related to my submission to the “innovative ideas” lightning talk / virtual poster session of the 2020 MOSS Meetup organized by ICfL.

    + +

    The SIFT Moves

    + + + +

    SIFT Moves at CWI

    + +

    Here’s a couple components of “Source Sifter,” a badge in the CWI “Research Basics Badge Set”:

    + + + + + + + + + + +
    + + + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/site.webmanifest b/site.webmanifest new file mode 100644 index 000000000..b20abb7cb --- /dev/null +++ b/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "", + "short_name": "", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 000000000..9638bc7bd --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,883 @@ + + + +https://ryanpatrickrandall.com/notes/ADHD-tech/apple-watch-ADHD +2022-04-18T00:00:00-06:00 + + +https://ryanpatrickrandall.com/notes/ADHD-tech/about-ADHD-technologies +2022-04-07T00:00:00-06:00 + + +https://ryanpatrickrandall.com/notes/ADHD-tech/index +2023-11-27T01:37:22-07:00 + + +https://ryanpatrickrandall.com/notes/ADHD/index +2023-11-27T01:37:22-07:00 + + +https://ryanpatrickrandall.com/notes/Accessibility/index +2023-11-27T01:37:22-07:00 + + +https://ryanpatrickrandall.com/notes/Keywords/index +2023-11-27T01:37:22-07:00 + + +https://ryanpatrickrandall.com/notes/Listening/index +2023-11-27T01:37:22-07:00 + + +https://ryanpatrickrandall.com/notes/Note-taking/Approaches/index +2023-11-27T01:37:22-07:00 + + +https://ryanpatrickrandall.com/notes/Note-taking/Dendron/literature-notes-dendron +2023-01-22T00:00:00-07:00 + + +https://ryanpatrickrandall.com/notes/Note-taking/Dendron/beginning-to-use-dendron +2022-04-22T00:00:00-06:00 + + +https://ryanpatrickrandall.com/notes/Note-taking/Approaches/casey-boyle-something-like-reading-ethics +2023-01-22T00:00:00-07:00 + + +https://ryanpatrickrandall.com/notes/Note-taking/Approaches/rhetorical-precis +2023-01-22T00:00:00-07:00 + + +https://ryanpatrickrandall.com/notes/Note-taking/Dendron/index +2023-11-27T01:37:22-07:00 + + +https://ryanpatrickrandall.com/notes/Note-taking/Dendron/task-tracking-in-dendron +2022-11-01T00:00:00-06:00 + + +https://ryanpatrickrandall.com/notes/Note-taking/Obsidian/beginning-to-use-obsidian +2023-10-12T00:00:00-06:00 + + +https://ryanpatrickrandall.com/notes/Note-taking/Obsidian/index +2023-11-27T01:37:22-07:00 + + +https://ryanpatrickrandall.com/notes/Note-taking/index +2023-11-27T01:37:22-07:00 + + +https://ryanpatrickrandall.com/notes/Pedagogy/index +2023-11-27T01:37:22-07:00 + + +https://ryanpatrickrandall.com/notes/Reading/Articles/index +2023-11-27T01:37:22-07:00 + + +https://ryanpatrickrandall.com/notes/Reading/Books/wark-capital-is-dead +2023-02-02T00:00:00-07:00 + + +https://ryanpatrickrandall.com/notes/Note-taking/Obsidian/obsidian-plugins +2023-11-18T00:00:00-07:00 + + +https://ryanpatrickrandall.com/notes/Note-taking/Obsidian/obsidian-tasks-plugin-patterns +2023-11-19T00:00:00-07:00 + + +https://ryanpatrickrandall.com/notes/Reading/Books/purdon-modernist-informatics +2023-11-02T19:08:02-06:00 + + +https://ryanpatrickrandall.com/notes/Reading/Articles/riggs-and-linder-actively-engaging-students +2023-02-01T00:00:00-07:00 + + +https://ryanpatrickrandall.com/notes/Reading/Books/hall-policing-the-crisis +2023-02-01T00:00:00-07:00 + + +https://ryanpatrickrandall.com/notes/Reading/Books/index +2023-11-27T01:37:22-07:00 + + +https://ryanpatrickrandall.com/notes/Reading/Books/lee-overwhelmed +2023-11-12T00:00:00-07:00 + + +https://ryanpatrickrandall.com/notes/Reading/index +2023-11-27T01:37:22-07:00 + + +https://ryanpatrickrandall.com/notes/Snippets/index +2023-11-27T01:37:22-07:00 + + +https://ryanpatrickrandall.com/notes/Snippets/information-informatics +2020-09-20T00:00:00-06:00 + + +https://ryanpatrickrandall.com/notes/Technology/Jekyll/index +2023-11-27T01:37:22-07:00 + + +https://ryanpatrickrandall.com/notes/Technology/Social-Media/index +2023-11-27T01:37:22-07:00 + + +https://ryanpatrickrandall.com/notes/Technology/VS-Code/index +2023-11-27T01:37:22-07:00 + + +https://ryanpatrickrandall.com/notes/Technology/VS-Code/vs-code +2020-09-20T00:00:00-06:00 + + +https://ryanpatrickrandall.com/notes/Technology/VS-Code/daybreak-theme +2023-03-01T00:00:00-07:00 + + +https://ryanpatrickrandall.com/notes/Accessibility/math-a11y +2022-05-04T00:00:00-06:00 + + +https://ryanpatrickrandall.com/notes/Technology/Social-Media/mastodon-apps +2022-11-19T00:00:00-07:00 + + +https://ryanpatrickrandall.com/notes/Technology/Social-Media/mastodon-settings +2022-11-20T00:00:00-07:00 + + +https://ryanpatrickrandall.com/notes/Technology/Jekyll/jekyll-guides +2023-01-07T00:00:00-07:00 + + +https://ryanpatrickrandall.com/notes/Technology/VS-Code/vs-code-snippets +2023-04-02T14:15:57-06:00 + + +https://ryanpatrickrandall.com/notes/Technology/VS-Code/vs-code-spellcheck-squiggles +2023-04-01T19:02:44-06:00 + + +https://ryanpatrickrandall.com/notes/Technology/index +2023-11-27T01:37:22-07:00 + + +https://ryanpatrickrandall.com/notes/emerging-notes +2023-11-27T01:37:22-07:00 + + +https://ryanpatrickrandall.com/notes/index +2023-11-27T01:37:22-07:00 + + +https://ryanpatrickrandall.com/new-site +2015-04-27T01:02:36-06:00 + + +https://ryanpatrickrandall.com/test-one +2014-09-07T19:01:01-06:00 + + +https://ryanpatrickrandall.com/blog/new-directions-in-information-fluency +2014-09-07T21:01:01-06:00 + + +https://ryanpatrickrandall.com/bigfoot-spotting +2015-05-31T00:00:00-06:00 + + +https://ryanpatrickrandall.com/review-of-online-archive-of-california +2014-09-19T21:55:19-06:00 + + +https://ryanpatrickrandall.com/software-carpentry-workshop-reflections +2014-10-12T20:50:07-06:00 + + +https://ryanpatrickrandall.com/paper-planned-obsolescence-and-digital-libraries +2014-11-30T19:35:46-07:00 + + +https://ryanpatrickrandall.com/critlib-chatty-critical-librarianship-on-twitter +2014-12-08T21:47:52-07:00 + + +https://ryanpatrickrandall.com/how-do-you-take-notes-or-markdown-and-bullet-journals +2015-01-20T21:48:34-07:00 + + +https://ryanpatrickrandall.com/freire-and-critical-librarianship +2015-01-25T21:07:23-07:00 + + +https://ryanpatrickrandall.com/critlib-makerspaces +2015-03-21T17:45:47-06:00 + + +https://ryanpatrickrandall.com/wojnarowicz-on-a-sphere +2015-04-02T00:10:24-06:00 + + +https://ryanpatrickrandall.com/learning-subjectives +2015-04-20T20:17:22-06:00 + + +https://ryanpatrickrandall.com/del-hack-del-quirk-your-presentations +2015-04-23T16:17:10-06:00 + + +https://ryanpatrickrandall.com/everything-counts-in-affective-amounts +2015-04-28T20:34:48-06:00 + + +https://ryanpatrickrandall.com/rhizo15-week-three +2015-05-17T18:50:53-06:00 + + +https://ryanpatrickrandall.com/quick-thoughts-on-method +2015-06-12T18:00:37-06:00 + + +https://ryanpatrickrandall.com/reveal-js-hack-library-school +2015-06-21T00:38:52-06:00 + + +https://ryanpatrickrandall.com/critpotato-rhizo15-week-four +2015-07-05T14:20:07-06:00 + + +https://ryanpatrickrandall.com/all-hail-cloud-storage +2015-07-17T18:43:42-06:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/weekly-assemblage-2015-week-36 +2015-09-05T13:45:03-06:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/weekly-assemblage-2015-week-37 +2015-09-13T17:48:43-06:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/weekly-assemblage-2015-week-38 +2015-09-24T22:09:30-06:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/weekly-assemblage-2015-week-39 +2015-09-26T18:31:39-06:00 + + +https://ryanpatrickrandall.com/this-is-not-a-pipette +2015-09-27T22:46:08-06:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/weekly-assemblage-2015-week-40 +2015-10-10T22:19:26-06:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/weekly-assemblage-2015-week-41 +2015-10-11T23:39:58-06:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/weekly-assemblage-2015-week-42 +2015-10-18T21:08:13-06:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/weekly-assemblage-2015-week-43 +2015-10-25T11:31:37-06:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/weekly-assemblage-2015-week-44 +2015-11-01T19:44:33-07:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/weekly-assemblage-2015-week-45 +2015-11-08T21:09:05-07:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/WA-2015-week-46-Massumi-and-North +2015-11-15T20:42:51-07:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2015-week-47 +2015-11-22T15:01:28-07:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2015-week-48 +2015-11-29T11:54:09-07:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2015-week-49 +2015-12-06T16:07:53-07:00 + + +https://ryanpatrickrandall.com/critlib-feelings +2015-12-13T10:46:03-07:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/weekly-whaaa +2016-01-09T22:50:33-07:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2016-week-01 +2016-01-10T01:06:24-07:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2016-week-02 +2016-01-17T10:25:41-07:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2016-week-03 +2016-01-24T16:06:36-07:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2016-week-04 +2016-01-31T23:29:44-07:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2016-week-05 +2016-02-03T23:58:53-07:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2016-week-06 +2016-02-04T23:31:28-07:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2016-week-07 +2016-02-14T13:44:01-07:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2016-week-08 +2016-03-04T23:31:05-07:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2016-week-12 +2016-03-30T00:03:57-06:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2016-week-14 +2016-04-10T01:22:26-06:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2016-week-15 +2016-04-10T23:54:23-06:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2016-week-16 +2016-04-17T23:32:45-06:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2016-week-17 +2016-04-26T00:07:48-06:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2016-week-18 +2016-05-05T00:09:09-06:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2016-week-19 +2016-05-08T22:42:06-06:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2016-week-27 +2016-07-06T13:42:45-06:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2016-week-31 +2016-08-07T20:45:48-06:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2016-week-32 +2016-08-14T22:18:40-06:00 + + +https://ryanpatrickrandall.com/critical-reflection +2016-12-18T00:20:10-07:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2017-week-01 +2017-01-08T01:33:09-07:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2017-week-09 +2017-03-06T17:01:39-07:00 + + +https://ryanpatrickrandall.com/my-ala-annual-2018-schedule +2018-06-19T12:34:53-06:00 + + +https://ryanpatrickrandall.com/while-you-are-not-safe-i-am-not-safe +2020-07-03T19:50:00-06:00 + + +https://ryanpatrickrandall.com/monthly-signal-boost/introducing-monthly-signal-boosts +2020-07-01T00:00:00-06:00 + + +https://ryanpatrickrandall.com/monthly-signal-boost/july-2020-monthly-signal-boost +2020-07-19T00:00:00-06:00 + + +https://ryanpatrickrandall.com/sift-links +2020-07-29T13:34:53-06:00 + + +https://ryanpatrickrandall.com/notes/new-note-on-apple-watch-and-adhd +2020-07-30T13:51:53-06:00 + + +https://ryanpatrickrandall.com/monthly-signal-boost/august-2020-monthly-signal-boost +2020-08-31T13:34:53-06:00 + + +https://ryanpatrickrandall.com/notes/new-note-on-adhd-technologies +2020-09-04T13:51:53-06:00 + + +https://ryanpatrickrandall.com/notes/new-note-on-informatics-readings +2020-09-04T13:51:53-06:00 + + +https://ryanpatrickrandall.com/notes/new-note-on-vs-code +2020-09-04T13:51:53-06:00 + + +https://ryanpatrickrandall.com/notes/new-note-on-keeping-literature-notes-in-dendron +2021-06-21T13:51:53-06:00 + + +https://ryanpatrickrandall.com/notes/new-note-on-the-daybreak-theme +2022-04-18T13:51:53-06:00 + + +https://ryanpatrickrandall.com/notes/new-note-beginning-to-use-dendron +2022-04-22T13:51:53-06:00 + + +https://ryanpatrickrandall.com/notes/new-note-on-math-accessibility +2022-05-04T13:51:53-06:00 + + +https://ryanpatrickrandall.com/notes/new-note-on-task-tracking-in-dendron +2022-10-26T13:51:53-06:00 + + +https://ryanpatrickrandall.com/notes/new-note-on-mastodon-ios-apps +2022-11-19T12:51:53-07:00 + + +https://ryanpatrickrandall.com/notes/new-note-on-mastodon-settings +2022-11-20T12:51:53-07:00 + + +https://ryanpatrickrandall.com/blips/introducing-blips-and-link-rhizomes +2023-01-01T12:34:53-07:00 + + +https://ryanpatrickrandall.com/notes/jekyll-guides-note +2023-01-07T12:51:53-07:00 + + +https://ryanpatrickrandall.com/blips/phone-to-blog-blip-workflow +2023-01-18T20:34:53-07:00 + + +https://ryanpatrickrandall.com/notes/new-note-on-rhetorical-precis +2023-01-22T19:20:53-07:00 + + +https://ryanpatrickrandall.com/notes/new-note-on-casey-boyles-something-like-a-reading-ethics +2023-01-22T19:25:53-07:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2023-week-09 +2023-03-05T20:04:41-07:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2023-week-10 +2023-03-10T17:04:41-07:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2023-week-12 +2023-03-26T00:00:00-06:00 + + +https://ryanpatrickrandall.com/notes/new-note-on-snippets-and-vs-code +2023-04-01T19:04:04-06:00 + + +https://ryanpatrickrandall.com/notes/new-note-on-spellcheck-squiggles-in-vs-code +2023-04-30T13:56:14-06:00 + + +https://ryanpatrickrandall.com/weekly-assemblage/wa-2023-week-17 +2023-04-30T13:49:46-06:00 + + +https://ryanpatrickrandall.com/light-mode-in-progress +2023-10-12T21:44:14-06:00 + + +https://ryanpatrickrandall.com/notes/beginning-to-use-obsidian +2023-10-12T21:32:31-06:00 + + +https://ryanpatrickrandall.com/notes/obsidian-plugins +2023-10-23T11:08:34-06:00 + + +https://ryanpatrickrandall.com/acwrimo2023 +2023-10-31T17:47:58-06:00 + + +https://ryanpatrickrandall.com/notes/obsidian-tasks-patterns +2023-11-18T19:52:10-07:00 + + +https://ryanpatrickrandall.com/wiki/ADHDtech/about-ADHD-technologies +2020-09-04T00:00:00-06:00 + + +https://ryanpatrickrandall.com/about/ +2020-07-19T00:00:00-06:00 + + +https://ryanpatrickrandall.com/wiki/ADHDtech/apple-watch-adhd +2020-07-30T00:00:00-06:00 + + +https://ryanpatrickrandall.com/talks/capal16 + + +https://ryanpatrickrandall.com/categories/ + + +https://ryanpatrickrandall.com/colophon/ +2022-08-14T00:00:00-06:00 + + +https://ryanpatrickrandall.com/cv/ +2023-11-19T13:36:20-07:00 + + +https://ryanpatrickrandall.com/wiki/Articles/hall-new-identities +2020-07-18T00:00:00-06:00 + + +https://ryanpatrickrandall.com/wiki/Articles/hooks-buddhism +2020-07-29T00:00:00-06:00 + + +https://ryanpatrickrandall.com/wiki/Snippets/ + + +https://ryanpatrickrandall.com/wiki/Pedagogy/ + + +https://ryanpatrickrandall.com/wiki/ADHD/ + + +https://ryanpatrickrandall.com/wiki/ADHDtech/ + + +https://ryanpatrickrandall.com/wiki/Books/ + + +https://ryanpatrickrandall.com/wiki/Music/ + + +https://ryanpatrickrandall.com/wiki/Technology/ + + +https://ryanpatrickrandall.com/wiki/Articles/ + + +https://ryanpatrickrandall.com/wiki/ + + +https://ryanpatrickrandall.com/ + + +https://ryanpatrickrandall.com/wiki/Snippets/information-informatics +2020-09-20T00:00:00-06:00 + + +https://ryanpatrickrandall.com/links-rhizome/ +2023-04-14T00:00:00-06:00 + + +https://ryanpatrickrandall.com/links/ +2014-04-04T04:13:00-06:00 + + +https://ryanpatrickrandall.com/now/ +2023-05-18T00:00:00-06:00 + + +https://ryanpatrickrandall.com/portfolio/ +2015-10-10T11:30:00-06:00 + + +https://ryanpatrickrandall.com/reading/ + + +https://ryanpatrickrandall.com/recommended-reading/ +2016-03-06T00:00:00-07:00 + + +https://ryanpatrickrandall.com/recommended-readings-critical-librarianship/ +2016-03-26T23:20:29-06:00 + + +https://ryanpatrickrandall.com/recommended-readings-critical-theory/ +2016-03-26T23:20:29-06:00 + + +https://ryanpatrickrandall.com/sandbox/ +2022-09-09T00:00:00-06:00 + + +https://ryanpatrickrandall.com/tags/ + + +https://ryanpatrickrandall.com/talks/ +2016-06-28T00:00:00-06:00 + + +https://ryanpatrickrandall.com/uses/ +2023-11-21T00:00:00-07:00 + + +https://ryanpatrickrandall.com/posts/ + + +https://ryanpatrickrandall.com/talks/plugin/markdown/example + + +https://ryanpatrickrandall.com/talks/test/simple + + +https://ryanpatrickrandall.com/talks/css/theme/ + + +https://ryanpatrickrandall.com/page2/ + + +https://ryanpatrickrandall.com/page3/ + + +https://ryanpatrickrandall.com/page4/ + + +https://ryanpatrickrandall.com/page5/ + + +https://ryanpatrickrandall.com/page6/ + + +https://ryanpatrickrandall.com/page7/ + + +https://ryanpatrickrandall.com/page8/ + + +https://ryanpatrickrandall.com/page9/ + + +https://ryanpatrickrandall.com/page10/ + + +https://ryanpatrickrandall.com/page11/ + + +https://ryanpatrickrandall.com/page12/ + + +https://ryanpatrickrandall.com/page13/ + + +https://ryanpatrickrandall.com/page14/ + + +https://ryanpatrickrandall.com/page15/ + + +https://ryanpatrickrandall.com/page16/ + + +https://ryanpatrickrandall.com/page17/ + + +https://ryanpatrickrandall.com/page18/ + + +https://ryanpatrickrandall.com/page19/ + + +https://ryanpatrickrandall.com/assets/images/ThinkingToolAlphaboxNotes.pdf +2023-11-27T01:35:47-07:00 + + +https://ryanpatrickrandall.com/talks/bootstrapdemo.html +2023-11-27T01:35:47-07:00 + + +https://ryanpatrickrandall.com/talks/bsu.html +2023-11-27T01:35:47-07:00 + + +https://ryanpatrickrandall.com/talks/capal16.html +2023-11-27T01:35:47-07:00 + + +https://ryanpatrickrandall.com/talks/comm101.html +2023-11-27T01:35:47-07:00 + + +https://ryanpatrickrandall.com/talks/cwi101.html +2023-11-27T01:35:47-07:00 + + +https://ryanpatrickrandall.com/talks/cyoat.html +2023-11-27T01:35:47-07:00 + + +https://ryanpatrickrandall.com/talks/demo.html +2023-11-27T01:35:47-07:00 + + +https://ryanpatrickrandall.com/talks/dh+lib-draft.html +2023-11-27T01:35:47-07:00 + + +https://ryanpatrickrandall.com/talks/engl101.html +2023-11-27T01:35:47-07:00 + + +https://ryanpatrickrandall.com/talks/engl102.html +2023-11-27T01:35:47-07:00 + + +https://ryanpatrickrandall.com/talks/engl5581.html +2023-11-27T01:35:47-07:00 + + +https://ryanpatrickrandall.com/talks/engl6612.html +2023-11-27T01:35:47-07:00 + + +https://ryanpatrickrandall.com/talks/hacklibraryschool.html +2023-11-27T01:35:47-07:00 + + +https://ryanpatrickrandall.com/talks/igc2019.html +2023-11-27T01:35:47-07:00 + + +https://ryanpatrickrandall.com/talks/ +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/indexY.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/itrc.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/plugin/markdown/example.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/plugin/notes-server/notes.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/plugin/notes/notes.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/swila2017.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/test/examples/barebones.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/test/examples/embedded-media.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/test/examples/math.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/test/examples/slide-backgrounds.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/test/examples/slide-transitions.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/test/test-dependencies-async.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/test/test-dependencies.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/test/test-grid-navigation.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/test/test-iframes.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/test/test-markdown-element-attributes.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/test/test-markdown-external.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/test/test-markdown-options.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/test/test-markdown-slide-attributes.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/test/test-markdown.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/test/test-pdf.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/test/test-plugins.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/test/test-state.html +2023-11-27T01:35:48-07:00 + + +https://ryanpatrickrandall.com/talks/test/test.html +2023-11-27T01:35:48-07:00 + + diff --git a/software-carpentry-workshop-reflections.html b/software-carpentry-workshop-reflections.html new file mode 100644 index 000000000..e6f750a80 --- /dev/null +++ b/software-carpentry-workshop-reflections.html @@ -0,0 +1,669 @@ + + + + + + +Software Carpentry Workshop Reflections — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + +
    + +
    +

    + +

    + + +

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

    + + +
    + + +
    + + + + +

    Welcome to the Command Line

    + +

    It wasn’t quite Tron: I jumped into the world of computing for two days while taking a Software Carpentry workshop and it turned out highly illuminating without being threatening. This post aims to summarize what I learned & its relevance to librarians and/or digital humanities folks, encourage others to take/give similar workshops, and explain what I’d change about the workshop for librarians or digital humanities scholars.

    + + + +

    Software Carpentry

    + +

    Since 1998 Software Carpentry, a volunteer organization, has been introducing basic computing skills to scientists. The workshops focus on Unix commands & programs, Python programming basics, Git for version control, and MySQL for database management. From a pedagogical standpoint, I particularly like that their teaching materials introduce different personae and scenarios to help participants grasp the real-world relevance of the technologies as they learn. From a “these tools should be universally accessible” standpoint, I’m grateful that Software Carpentry puts all their materials online for free. If you’re interested in the specifics of their lessons, check them out here. As part of my campus’s ASIS&T Student Chapter, I can easily imagine selecting portions of their materials as the basis for much shorter workshops, then pointing people to the full online materials to learn more on their own.

    + +

    My Perspective

    + +

    I came into the workshop familiar with some basic Unix commands and use of GitHub from the graphic user interface. For instance, I generate my website from the command line using a program called Jekyll and then push it to GitHub’s servers using their Mac app. So although I had a functional mental model for how these things work, the Software Carpentry lessons helped extend my knowledge into much more powerful tools. Much like when learning a foreign language, the immersive aspect of grappling with these systems for a sustained period of time seems to have helped things “stick.” Since you probably know whether a programming language (Python) or a database (MySQL) would be useful or interesting for you, I’ll only write about Git in depth.

    + +

    If you ever write anything for school or work, you could benefit from using Git. It’s version control software, meaning that it helps keep track of changes in files. Unlike the “track changes” functionality you’re probably familiar with in Microsoft Word, Git accomodates collaboration at huge scales. For software or anything else that benefits from separating stable and development versions, Git uses a model of branching. Say you’ve made a simple script that works, and you want to share it but also want to keep adding new features. Git lets you simultaneously have a reliable output and others that are under constant revision and improvement. When you’re satisfied that the new features haven’t added anything undesirable into those versions, you can pull the new developments into the reliable version with ease.

    + +

    Moreover, Git isn’t just for programs or scripts—it’s equally superb for good ‘ol paragraphs of text! Since I’ve previously been burned by losing files due to hard drives crashing and programs becoming obsolete, I’ve taken to writing in plain text using Markdown. (If you want to see how it works, here’s a useful playpen.) I can use Git to track the development of a particular file that I’m working on, with brief annotations for every stage that I save (or “commit”). This is great news! I wouldn’t necessarily want to put the working draft of an academic article on GitHub for just anyone to stumble across, but by using Git through the command line I can have that same version control power in the cozy confines of my own hard drive. (If you’re not into the whole brevity Markdown thing, it’s apparently possible to use Git with Microsoft Word as well, should you so desire. But seriously, just do yourself a favor and write in Markdown, especially if anything you do is destined for the web.)

    + +

    Recommendations for Workshops Aimed at Librarians and Digital Humanities Folks

    + +

    Using an EtherPad allowed us to take live collaborative notes, as well as chatting in a side bar. This, along with using blue and orange sticky notes to indicate whether we’re doing well or having trouble, made what could have been an isolating, each-to-their-own-screen experience much more collective. Our particular EtherPad persists after the end of the workshop, so we can all go back and brush up on the different commands and things. Sadly, far fewer people showed up to the workshop than signed up, which meant that there were a lot of spaces that could have been used by others. The incentive model that Indiana’s Statewide IT conference apparently uses is that they charge nothing to attend but charge about $15 if you don’t show up, which seems the best way of making these accessible to the greatest number of possible participants. I’d highly recommend that model for anyone giving one of these in the future. If you’re interested in taking or leading a workshop, they’ve got a page for more information. The EtherPad, sticky notes, and incentive model would all be useful strategies for any workshop.

    + +

    For librarians and DH people, the MySQL portion of the Software Carpentry workshop could have been greatly reduced. It does certainly seem worth demonstrating how nicely MySQL interacts with Python scripts and with the iPython Notebook viewer. However—and this is a complement to its ease of use!—MySQL seems straightforward enough that anyone interested could learn from Software Carpentry’s online documentation rather than walking through it in detail as a group. What felt far more useful to do in person was something that Jeremiah Lant, one of our presenters, improvised in our last 45 minutes after we collectively decided to skip the remainder of the MySQL stuff: we walked through writing a Unix shell script that combines the concept of for loops (covered in the Python section) to determine something about a data set, then write those findings to a text file. This exercise neatly tied together many of the new skills that we’d gained and applied them to a scenario that our Assessment Librarian, Andrew Asher, faces routinely.

    + +

    As a librarian, I can certainly see that these particular tech tools would work well for any countable data: circulation, gate counts, collection statistics, etc. They have less immediate relevance to digital humanities, since what’s interesting about humanities texts rarely arrives in enumerated form. However, having spent two days familiarizing myself with how these tools operate makes it much easier for me to conceive of how to formulate questions about texts using these tools. Immersing myself in the command line has also made me generally more comfortable exploring a side of my computer I’d hitherto treated as a threatening realm. I’m not going to register for a lightcycle just yet, but the Software Carpentry workshop certainly made me even more eager to continue learning more programming tools.

    + +

    TL;DR

    + +
      +
    • Check Software Carpentry’s Future Workshops page to see if there’s one happening near you. Take one if you can!
    • +
    • If you lead one for librarians and digital humanities people, downplay MySQL in favor of building scripts to handle bulk tasks.
    • +
    • Use EtherPad if you’re leading a workshop and want people to have collaborative notes & chat in the same place. (It’s like Google Docs only without needing accounts, permissions, etc.)
    • +
    • Consider having a “pay if you don’t come” policy to create an incentive for all who register to show up.
    • +
    + + + + +
    + + + + + + + + +
    + + +
    + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/tags/index.html b/tags/index.html new file mode 100644 index 000000000..86c68bad4 --- /dev/null +++ b/tags/index.html @@ -0,0 +1,8635 @@ + + + + + + +Posts by Tag — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    + + + + +
    + + + + + +
    + +

    Posts by Tag

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

    critlib chats

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

    + + critlib #feelings + + +

    + + +

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

    + + +

    Why do I #critlib? Because another librarianship is possible. +

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

    + + Weekly Assemblage 2015 Week 43 + + +

    + + +

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

    + + +

    A #critlib chat on gender & leadership in LIS, plus some history links. +

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

    + + Weekly Assemblage 2015 Week 41 + + +

    + + +

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

    + + +

    Talking about librarianship values: objectivity as a value and valuing inclusivity enough to work toward it in earnest. And again—sorry, Eduardo. +

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

    + + Weekly Assemblage 2015 Week 37 + + +

    + + +

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

    + + +

    A #critlib chat on information & migrant populations; threats to the Tor exit node in Kilton Public Library; CFP for papers on whiteness in LIS; study on...

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

    + + Critical Hot Potato! aka #Rhizo15 Week Four + + +

    + + +

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

    + + +

    Reflecting on #critlib morphs into #critpotato for my much-delayed Week Four of #rhizo15 post, examining how online learning operates. +

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

    + + #critlib Makerspaces + + +

    + + +

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

    + + +

    I write about moderating a #critlib Twitter chat on the constructivist potentials and neoliberal downsides of makerspaces, as well as briefly describe the mo...

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

    + + Freire and Critical Librarianship + + +

    + + +

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

    + + +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship. +

    +
    +
    + + + + + + +
    + +
    + + +
    + Back to top ↑ +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    meta

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

    + + WA 2016 Week 31: Design Things Galore + + +

    + + +

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

    + + +

    Design thinking in Idaho libraries, button templates from Librarian Design Share and Char Booth, and a few minor site font updates. +

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

    + + WA 2016 Week 17: Research Notebook is Go! + + +

    + + +

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

    + + +

    Much like with succulents, I’ve planted an offshoot of this blog to see whether it’ll take root. Open Humanities Research Notebooks—come and join the future™. +

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

    + + WA 2016 Week 12: DERAIL, Site Updates + + +

    + + +

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

    + + +

    DERAIL 2016 student forum at Simmons! Also site updates — recommended readings pages and deep links with Anchor.js. +

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

    + + Weekly Whaaa…? + + +

    + + +

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

    + + +

    Why weekly? Why assemblage? Why Fluxus? And what’s that “sous les pavés, la plage” thing about? +

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

    + + Weekly Assemblage 2015 Week 45 + + +

    + + +

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

    + + +

    Three links & lots of enthusiasm! Elmborg’s “Literacies Large and Small,” a Time Management mega post, & how STEM relates to the liberal arts. +

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

    + + All Hail Cloud Storage + + +

    + + +

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

    + + +

    Dropbox has both saved me from computer problems and helped me work more ubiquitously, so I sang the praises of it and other cloud storage at Hack Library Sc...

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

    + + Bigfoot Spotting and Other Jekyll Adventures + + +

    + + +

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

    + + +

    A post where I describe trying—and thus far, failing—to use Bigfoot.js to make footnotes more engaging in a Jekyll/GitHub Pages blog. I’ll revisit this soon ...

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

    + + Test One + + +

    + + +

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

    + + +

    Here’s a stellar ditty from Warp™ records that deserves being listened to with headphones or a subwoofer. +

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

    + + New Site + + +

    + + +

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

    + + +

    A Depeche Mode reference is more interesting than Hello World, isn’t it? +

    +
    +
    + + +
    + Back to top ↑ +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    pedagogy

    +
    + + + + + +
    +
    + +

    + + SIFT Links + + +

    + + +

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

    + + +

    Links related to a lightning talk for the 2020 MOSS Meetup about our switch from the CRAAP test to the SIFT moves. +

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

    + + Weekly Assemblage 2015 Week 42 + + +

    + + +

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

    + + +

    Live! Real! Humans! (in the Classroom); Code Camps, the “Californian Ideology,” & Higher Ed’s Purpose; Open Access & “The Library of Forking Paths.” +

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

    + + Weekly Assemblage 2015 Week 39 + + +

    + + +

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

    + + +

    Getting library cards and appreciating some unexpected aspects of Maria Accardi’s Feminist Pedagogy for Library Instruction. +

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

    + + Presentation Alternatives: Reveal.js + + +

    + + +

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

    + + +

    Are you looking for a good alternative to PowerPoint or Keynotes? Here’s a Hack Library School post about an excellent free & open source one! +

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

    + + #Rhizo15 Week Three: "Content is People" + + +

    + + +

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

    + + +

    For Week Three of #rhizo15, I trace a few thoughts on content vs discontents or reification and the observable outcomes of human actions. +

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

    + + Learning Subjectives + + +

    + + +

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

    + + +

    For Week One of #rhizo15, I write about my predilection for research processes over writing outcomes & whether library “neutrality” thwarts supportive de...

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

    + + #critlib Makerspaces + + +

    + + +

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

    + + +

    I write about moderating a #critlib Twitter chat on the constructivist potentials and neoliberal downsides of makerspaces, as well as briefly describe the mo...

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

    + + Freire and Critical Librarianship + + +

    + + +

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

    + + +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship. +

    +
    +
    + + +
    + Back to top ↑ +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    conferences

    +
    + + + + + +
    +
    + +

    + + SIFT Links + + +

    + + +

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

    + + +

    Links related to a lightning talk for the 2020 MOSS Meetup about our switch from the CRAAP test to the SIFT moves. +

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

    + + WA 2016 Week 12: DERAIL, Site Updates + + +

    + + +

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

    + + +

    DERAIL 2016 student forum at Simmons! Also site updates — recommended readings pages and deep links with Anchor.js. +

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

    + + Weekly Assemblage 2015 Week 40 + + +

    + + +

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

    + + +

    Starting at the College of Western Idaho & going to the Idaho Library Association 2015 Annual Conference! +

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

    + + New Directions in Information Fluency + + +

    + + +

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

    + + +

    Brief reflections on a talk about bringing digital humanities to the reference desk, which I co-presented with Katherine Ahnberg at the New Directions in Inf...

    +
    +
    + + +
    + Back to top ↑ +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    critical theory

    +
    + + + + + +
    +
    + +

    + + WA 2016 Week 02: Giroux on Neutrality + + +

    + + +

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

    + + +

    A culture of positivism, distinguishing between objectivity and objectivism, hegemony, false neutrality, values—this article has all sorts of relevance for l...

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

    + + critlib #feelings + + +

    + + +

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

    + + +

    Why do I #critlib? Because another librarianship is possible. +

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

    + + WA 2015 Week 46 Massumi and North + + +

    + + +

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

    + + +

    Enthusiasm about Massumi putting Deleuze in a nutshell! Analogies between the pedagogy & structural place of Writing Centers & libraries! Jekyll on t...

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

    + + Weekly Assemblage 2015 Week 38 + + +

    + + +

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

    + + +

    Driving from Bloomington, Indiana to Boise, Idaho; Luciano Floridi’s Information: A Very Short Introduction. +

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

    + + Weekly Assemblage 2015 Week 36 + + +

    + + +

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

    + + +

    Reflections on the second #radlibchat and a Library Freedom Presentation by Alison Macrina. +

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

    + + Critical Hot Potato! aka #Rhizo15 Week Four + + +

    + + +

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

    + + +

    Reflecting on #critlib morphs into #critpotato for my much-delayed Week Four of #rhizo15 post, examining how online learning operates. +

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

    + + Presentation Alternatives: Reveal.js + + +

    + + +

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

    + + +

    Are you looking for a good alternative to PowerPoint or Keynotes? Here’s a Hack Library School post about an excellent free & open source one! +

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

    + + Freire and Critical Librarianship + + +

    + + +

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

    + + +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship. +

    +
    +
    + + +
    + Back to top ↑ +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    digital humanities

    +
    + + + + + +
    +
    + +

    + + Everything Counts in Affective Amounts + + +

    + + +

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

    + + +

    Week Two of #rhizo15—How we might count the affective aspects of learning? Also, what potential does Git give us for making open humanities notebooks? +

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

    + + Hack Quirk Your Presentations + + +

    + + +

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

    + + +

    I wrote for Hack Library School about using quirky results or affordances to make your instruction sessions more engaging. +

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

    + + Learning Subjectives + + +

    + + +

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

    + + +

    For Week One of #rhizo15, I write about my predilection for research processes over writing outcomes & whether library “neutrality” thwarts supportive de...

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

    + + Wojnarowicz on a Sphere + + +

    + + +

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

    + + +

    Still under construction, this post will be about my process of making a map of artist David Wojnarowicz’s gallery exhibits for the NOAA Science on a Sphere. +

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

    + + Software Carpentry Workshop Reflections + + +

    + + +

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

    + + +

    Although aimed at scientists, Software Carpentry’s workshops offer great learning experience for librarians, digital humanities folks, and anyone looking to ...

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

    + + Review of Online Archive of California + + +

    + + +

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

    + + +

    The Online Archive of California lies somewhere between a finding aid and a digital library—and is a huge boon to researchers that would be worth emulating e...

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

    + + New Directions in Information Fluency + + +

    + + +

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

    + + +

    Brief reflections on a talk about bringing digital humanities to the reference desk, which I co-presented with Katherine Ahnberg at the New Directions in Inf...

    +
    +
    + + +
    + Back to top ↑ +
    + + + +
    +

    tech tools

    +
    + + + + + +
    +
    + +

    + + WA 2017 Week 09: Badges, Type, BibTeX + + +

    + + +

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

    + + +

    Briefly linking to Emily Ford’s article about badges, a short reference about using type on the web, and getting going with a bibliography tool. +

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

    + + WA 2016 Week 07: Tools for Thinking + + +

    + + +

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

    + + +

    Tools for Thinking (for information literacy instruction) and Tech Tools for Keeping Thoughts in Order (using Atom and its packages) +

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

    + + All Hail Cloud Storage + + +

    + + +

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

    + + +

    Dropbox has both saved me from computer problems and helped me work more ubiquitously, so I sang the praises of it and other cloud storage at Hack Library Sc...

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

    + + Presentation Alternatives: Reveal.js + + +

    + + +

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

    + + +

    Are you looking for a good alternative to PowerPoint or Keynotes? Here’s a Hack Library School post about an excellent free & open source one! +

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

    + + Everything Counts in Affective Amounts + + +

    + + +

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

    + + +

    Week Two of #rhizo15—How we might count the affective aspects of learning? Also, what potential does Git give us for making open humanities notebooks? +

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

    + + Bigfoot Spotting and Other Jekyll Adventures + + +

    + + +

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

    + + +

    A post where I describe trying—and thus far, failing—to use Bigfoot.js to make footnotes more engaging in a Jekyll/GitHub Pages blog. I’ll revisit this soon ...

    +
    +
    + + +
    + Back to top ↑ +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    critical information literacy

    +
    + + + + + +
    +
    + +

    + + WA 2015 Week 47 Schoofs and Battista + + +

    + + +

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

    + + +

    Articles from LOEX Quarterly (one by Schoofs, another by Battista) that look at learning beyond the library’s space. +

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

    + + WA 2015 Week 46 Massumi and North + + +

    + + +

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

    + + +

    Enthusiasm about Massumi putting Deleuze in a nutshell! Analogies between the pedagogy & structural place of Writing Centers & libraries! Jekyll on t...

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

    + + Weekly Assemblage 2015 Week 45 + + +

    + + +

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

    + + +

    Three links & lots of enthusiasm! Elmborg’s “Literacies Large and Small,” a Time Management mega post, & how STEM relates to the liberal arts. +

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

    + + Weekly Assemblage 2015 Week 42 + + +

    + + +

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

    + + +

    Live! Real! Humans! (in the Classroom); Code Camps, the “Californian Ideology,” & Higher Ed’s Purpose; Open Access & “The Library of Forking Paths.” +

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

    + + Weekly Assemblage 2015 Week 41 + + +

    + + +

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

    + + +

    Talking about librarianship values: objectivity as a value and valuing inclusivity enough to work toward it in earnest. And again—sorry, Eduardo. +

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

    + + Weekly Assemblage 2015 Week 39 + + +

    + + +

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

    + + +

    Getting library cards and appreciating some unexpected aspects of Maria Accardi’s Feminist Pedagogy for Library Instruction. +

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

    + + #Rhizo15 Week Three: "Content is People" + + +

    + + +

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

    + + +

    For Week Three of #rhizo15, I trace a few thoughts on content vs discontents or reification and the observable outcomes of human actions. +

    +
    +
    + + +
    + Back to top ↑ +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    hack library school

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

    + + All Hail Cloud Storage + + +

    + + +

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

    + + +

    Dropbox has both saved me from computer problems and helped me work more ubiquitously, so I sang the praises of it and other cloud storage at Hack Library Sc...

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

    + + Presentation Alternatives: Reveal.js + + +

    + + +

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

    + + +

    Are you looking for a good alternative to PowerPoint or Keynotes? Here’s a Hack Library School post about an excellent free & open source one! +

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

    + + Hack Quirk Your Presentations + + +

    + + +

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

    + + +

    I wrote for Hack Library School about using quirky results or affordances to make your instruction sessions more engaging. +

    +
    +
    + + + + + + +
    + +
    + + + + + + +
    + +
    + + +
    + Back to top ↑ +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    makerspaces

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

    + + WA 2015 Week 48 Fister, Kurz, Vecchione + + +

    + + +

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

    + + +

    Unanticipated Costs of “Doing More with Less”; Be Yr Own Her@; Making It Known that Libraraies are Spaces for Making +

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

    + + #critlib Makerspaces + + +

    + + +

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

    + + +

    I write about moderating a #critlib Twitter chat on the constructivist potentials and neoliberal downsides of makerspaces, as well as briefly describe the mo...

    +
    +
    + + +
    + Back to top ↑ +
    + + + + + +
    +

    rhizo15

    +
    + + + + + +
    +
    + +

    + + Critical Hot Potato! aka #Rhizo15 Week Four + + +

    + + +

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

    + + +

    Reflecting on #critlib morphs into #critpotato for my much-delayed Week Four of #rhizo15 post, examining how online learning operates. +

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

    + + #Rhizo15 Week Three: "Content is People" + + +

    + + +

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

    + + +

    For Week Three of #rhizo15, I trace a few thoughts on content vs discontents or reification and the observable outcomes of human actions. +

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

    + + Everything Counts in Affective Amounts + + +

    + + +

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

    + + +

    Week Two of #rhizo15—How we might count the affective aspects of learning? Also, what potential does Git give us for making open humanities notebooks? +

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

    + + Learning Subjectives + + +

    + + +

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

    + + +

    For Week One of #rhizo15, I write about my predilection for research processes over writing outcomes & whether library “neutrality” thwarts supportive de...

    +
    +
    + + +
    + Back to top ↑ +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    coursework

    +
    + + + + + +
    +
    + +

    + + Wojnarowicz on a Sphere + + +

    + + +

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

    + + +

    Still under construction, this post will be about my process of making a map of artist David Wojnarowicz’s gallery exhibits for the NOAA Science on a Sphere. +

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

    + + Review of Online Archive of California + + +

    + + +

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

    + + +

    The Online Archive of California lies somewhere between a finding aid and a digital library—and is a huge boon to researchers that would be worth emulating e...

    +
    +
    + + +
    + Back to top ↑ +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    neutrality

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

    + + WA 2016 Week 02: Giroux on Neutrality + + +

    + + +

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

    + + +

    A culture of positivism, distinguishing between objectivity and objectivism, hegemony, false neutrality, values—this article has all sorts of relevance for l...

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

    + + Learning Subjectives + + +

    + + +

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

    + + +

    For Week One of #rhizo15, I write about my predilection for research processes over writing outcomes & whether library “neutrality” thwarts supportive de...

    +
    +
    + + +
    + Back to top ↑ +
    + + + + + + + + + +
    +

    a11y

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

    + + Presentation Alternatives: Reveal.js + + +

    + + +

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

    + + +

    Are you looking for a good alternative to PowerPoint or Keynotes? Here’s a Hack Library School post about an excellent free & open source one! +

    +
    +
    + + +
    + Back to top ↑ +
    + + + +
    +

    privacy

    +
    + + + + + +
    +
    + +

    + + WA 2016 Week 04: Library Privacy + + +

    + + +

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

    + + +

    Library privacy session with ACLU Idaho’s Ritchie Eppink and Library Freedom Project’s Alison Macrina at Meridian Library District’s unBound technology lab. +

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

    + + Weekly Assemblage 2015 Week 37 + + +

    + + +

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

    + + +

    A #critlib chat on information & migrant populations; threats to the Tor exit node in Kilton Public Library; CFP for papers on whiteness in LIS; study on...

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

    + + Weekly Assemblage 2015 Week 36 + + +

    + + +

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

    + + +

    Reflections on the second #radlibchat and a Library Freedom Presentation by Alison Macrina. +

    +
    +
    + + +
    + Back to top ↑ +
    + + + + + + + + + +
    +

    librar* history

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

    + + Weekly Assemblage 2015 Week 43 + + +

    + + +

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

    + + +

    A #critlib chat on gender & leadership in LIS, plus some history links. +

    +
    +
    + + +
    + Back to top ↑ +
    + + + + + + + + + +
    +

    tools for thinking

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

    + + WA 2016 Week 07: Tools for Thinking + + +

    + + +

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

    + + +

    Tools for Thinking (for information literacy instruction) and Tech Tools for Keeping Thoughts in Order (using Atom and its packages) +

    +
    +
    + + +
    + Back to top ↑ +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    presentations

    +
    + + + + + +
    +
    + +

    + + Presentation Alternatives: Reveal.js + + +

    + + +

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

    + + +

    Are you looking for a good alternative to PowerPoint or Keynotes? Here’s a Hack Library School post about an excellent free & open source one! +

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

    + + New Directions in Information Fluency + + +

    + + +

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

    + + +

    Brief reflections on a talk about bringing digital humanities to the reference desk, which I co-presented with Katherine Ahnberg at the New Directions in Inf...

    +
    +
    + + +
    + Back to top ↑ +
    + + + + + + + + + + + + + + + +
    +

    markdown

    +
    + + + + + +
    +
    + +

    + + All Hail Cloud Storage + + +

    + + +

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

    + + +

    Dropbox has both saved me from computer problems and helped me work more ubiquitously, so I sang the praises of it and other cloud storage at Hack Library Sc...

    +
    +
    + + + + + + +
    + +
    + + +
    + Back to top ↑ +
    + + + + + + + +
    +

    moocmooc

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

    + + Freire and Critical Librarianship + + +

    + + +

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

    + + +

    For Week One of the Critical Pedagogy MOOC MOOC, I write about Paolo Freire’s problem-posing method and its potential links to critical librarianship. +

    +
    +
    + + +
    + Back to top ↑ +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    critical race studies

    +
    + + + + + +
    +
    + +

    + + Weekly Assemblage 2015 Week 41 + + +

    + + +

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

    + + +

    Talking about librarianship values: objectivity as a value and valuing inclusivity enough to work toward it in earnest. And again—sorry, Eduardo. +

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

    + + Weekly Assemblage 2015 Week 37 + + +

    + + +

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

    + + +

    A #critlib chat on information & migrant populations; threats to the Tor exit node in Kilton Public Library; CFP for papers on whiteness in LIS; study on...

    +
    +
    + + +
    + Back to top ↑ +
    + + + + + + + +
    +

    outreach

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

    + + Weekly Assemblage 2015 Week 44 + + +

    + + +

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

    + + +

    Halloween at CWI Library (Once Upon a Time); Readings I’m looking forward to; Taught my first library resources session. +

    +
    +
    + + +
    + Back to top ↑ +
    + + + +
    +

    infrastucture

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

    + + WA 2015 Week 46 Massumi and North + + +

    + + +

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

    + + +

    Enthusiasm about Massumi putting Deleuze in a nutshell! Analogies between the pedagogy & structural place of Writing Centers & libraries! Jekyll on t...

    +
    +
    + + +
    + Back to top ↑ +
    + + + + + + + + + +
    +

    critical librarianship history

    +
    + + + + + +
    + +
    + + + + + + +
    + +
    + + +
    + Back to top ↑ +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    digital libraries

    +
    + + + + + +
    + +
    + + +
    + Back to top ↑ +
    + + + + + + + + + +
    +

    notetaking

    +
    + + + + + +
    + +
    + + +
    + Back to top ↑ +
    + + + + + + + + + + + + + +
    +

    visual culture

    +
    + + + + + +
    +
    + +

    + + Wojnarowicz on a Sphere + + +

    + + +

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

    + + +

    Still under construction, this post will be about my process of making a map of artist David Wojnarowicz’s gallery exhibits for the NOAA Science on a Sphere. +

    +
    +
    + + +
    + Back to top ↑ +
    + + + + + + + +
    +

    instructional design & tools

    +
    + + + + + +
    +
    + +

    + + Hack Quirk Your Presentations + + +

    + + +

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

    + + +

    I wrote for Hack Library School about using quirky results or affordances to make your instruction sessions more engaging. +

    +
    +
    + + +
    + Back to top ↑ +
    + + + + + +
    +

    method

    +
    + + + + + +
    + +
    + + +
    + Back to top ↑ +
    + + + + + + + +
    +

    cfp

    +
    + + + + + +
    +
    + +

    + + Weekly Assemblage 2015 Week 37 + + +

    + + +

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

    + + +

    A #critlib chat on information & migrant populations; threats to the Tor exit node in Kilton Public Library; CFP for papers on whiteness in LIS; study on...

    +
    +
    + + +
    + Back to top ↑ +
    + + + + + +
    +

    gender

    +
    + + + + + +
    +
    + +

    + + Weekly Assemblage 2015 Week 43 + + +

    + + +

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

    + + +

    A #critlib chat on gender & leadership in LIS, plus some history links. +

    +
    +
    + + +
    + Back to top ↑ +
    + + + + + + + + + +
    +

    scholarly communication

    +
    + + + + + +
    + +
    + + +
    + Back to top ↑ +
    + + + + + +
    +

    dissent

    +
    + + + + + +
    + +
    + + +
    + Back to top ↑ +
    + + + + + +
    +

    instruction assessment

    +
    + + + + + +
    + +
    + + +
    + Back to top ↑ +
    + + + +
    +

    critical librarianship

    +
    + + + + + +
    + +
    + + +
    + Back to top ↑ +
    + + + +
    +

    design

    +
    + + + + + +
    +
    + +

    + + WA 2016 Week 31: Design Things Galore + + +

    + + +

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

    + + +

    Design thinking in Idaho libraries, button templates from Librarian Design Share and Char Booth, and a few minor site font updates. +

    +
    +
    + + +
    + Back to top ↑ +
    + + + +
    +

    badging

    +
    + + + + + +
    +
    + +

    + + WA 2017 Week 09: Badges, Type, BibTeX + + +

    + + +

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

    + + +

    Briefly linking to Emily Ford’s article about badges, a short reference about using type on the web, and getting going with a bibliography tool. +

    +
    +
    + + +
    + Back to top ↑ +
    + + + +
    +

    type

    +
    + + + + + +
    +
    + +

    + + WA 2017 Week 09: Badges, Type, BibTeX + + +

    + + +

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

    + + +

    Briefly linking to Emily Ford’s article about badges, a short reference about using type on the web, and getting going with a bibliography tool. +

    +
    +
    + + +
    + Back to top ↑ +
    + + + +
    +

    neurodiversity

    +
    + + + + + +
    + +
    + + +
    + Back to top ↑ +
    + + + +
    +

    LISMentalHealth

    +
    + + + + + +
    + +
    + + +
    + Back to top ↑ +
    + + + + +
    +
    +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/talks/Gruntfile.js b/talks/Gruntfile.js new file mode 100755 index 000000000..7e357530c --- /dev/null +++ b/talks/Gruntfile.js @@ -0,0 +1,189 @@ +const sass = require('node-sass'); + +module.exports = grunt => { + + require('load-grunt-tasks')(grunt); + + let port = grunt.option('port') || 8000; + let root = grunt.option('root') || '.'; + + if (!Array.isArray(root)) root = [root]; + + // Project configuration + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + meta: { + banner: + '/*!\n' + + ' * reveal.js <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd, HH:MM") %>)\n' + + ' * http://revealjs.com\n' + + ' * MIT licensed\n' + + ' *\n' + + ' * Copyright (C) 2019 Hakim El Hattab, http://hakim.se\n' + + ' */' + }, + + qunit: { + files: [ 'test/*.html' ] + }, + + uglify: { + options: { + banner: '<%= meta.banner %>\n', + ie8: true + }, + build: { + src: 'js/reveal.js', + dest: 'js/reveal.min.js' + } + }, + + sass: { + options: { + implementation: sass, + sourceMap: false + }, + core: { + src: 'css/reveal.scss', + dest: 'css/reveal.css' + }, + themes: { + expand: true, + cwd: 'css/theme/source', + src: ['*.sass', '*.scss'], + dest: 'css/theme', + ext: '.css' + } + }, + + autoprefixer: { + core: { + src: 'css/reveal.css' + } + }, + + cssmin: { + options: { + compatibility: 'ie9' + }, + compress: { + src: 'css/reveal.css', + dest: 'css/reveal.min.css' + } + }, + + jshint: { + options: { + curly: false, + eqeqeq: true, + immed: true, + esnext: true, + latedef: 'nofunc', + newcap: true, + noarg: true, + sub: true, + undef: true, + eqnull: true, + browser: true, + expr: true, + loopfunc: true, + globals: { + head: false, + module: false, + console: false, + unescape: false, + define: false, + exports: false, + require: false + } + }, + files: [ 'gruntfile.js', 'js/reveal.js' ] + }, + + connect: { + server: { + options: { + port: port, + base: root, + livereload: true, + open: true, + useAvailablePort: true + } + } + }, + + zip: { + bundle: { + src: [ + 'index.html', + 'css/**', + 'js/**', + 'lib/**', + 'images/**', + 'plugin/**', + '**.md' + ], + dest: 'reveal-js-presentation.zip' + } + }, + + watch: { + js: { + files: [ 'gruntfile.js', 'js/reveal.js' ], + tasks: 'js' + }, + theme: { + files: [ + 'css/theme/source/*.sass', + 'css/theme/source/*.scss', + 'css/theme/template/*.sass', + 'css/theme/template/*.scss' + ], + tasks: 'css-themes' + }, + css: { + files: [ 'css/reveal.scss' ], + tasks: 'css-core' + }, + test: { + files: [ 'test/*.html' ], + tasks: 'test' + }, + html: { + files: root.map(path => path + '/*.html') + }, + markdown: { + files: root.map(path => path + '/*.md') + }, + options: { + livereload: true + } + } + + }); + + // Default task + grunt.registerTask( 'default', [ 'css', 'js' ] ); + + // JS task + grunt.registerTask( 'js', [ 'jshint', 'uglify', 'qunit' ] ); + + // Theme CSS + grunt.registerTask( 'css-themes', [ 'sass:themes' ] ); + + // Core framework CSS + grunt.registerTask( 'css-core', [ 'sass:core', 'autoprefixer', 'cssmin' ] ); + + // All CSS + grunt.registerTask( 'css', [ 'sass', 'autoprefixer', 'cssmin' ] ); + + // Package presentation to archive + grunt.registerTask( 'package', [ 'default', 'zip' ] ); + + // Serve presentation locally + grunt.registerTask( 'serve', [ 'connect', 'watch' ] ); + + // Run tests + grunt.registerTask( 'test', [ 'jshint', 'qunit' ] ); + +}; diff --git a/talks/LICENSE b/talks/LICENSE new file mode 100644 index 000000000..09623076f --- /dev/null +++ b/talks/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2015 Hakim El Hattab, http://hakim.se + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/talks/README.md b/talks/README.md new file mode 100644 index 000000000..bd7138cd3 --- /dev/null +++ b/talks/README.md @@ -0,0 +1,7 @@ +# A V.I.L.E. henchman! + +> [You must be on the right track.](https://youtu.be/UEB9M_1XOP0?t=3m19s) + +You've found my semi-public page of talks made using the [Reveal.js](http://lab.hakim.se/reveal-js/) JavaScript presentation system. + +Well played. Have fun, super-sleuth. diff --git a/talks/bootstrapdemo.html b/talks/bootstrapdemo.html new file mode 100644 index 000000000..4cad776fe --- /dev/null +++ b/talks/bootstrapdemo.html @@ -0,0 +1,13 @@ + + + + + + Bootstrap Demo + + + + + + + + + + + +
    + + +
    +
    +

    Multimedia Development and User Experience Librarian Presentation

    +
    +
    +

    Ryan Randall

    +
    +

    2021-06-04

    +
    +
    Ryan smiling in a friendly close-up
    +
    +

    If you'd like to follow along, browse to: https://www.ryanpatrickrandall.com/talks/bsu.html +

    + +
    +
    +

    My Goals for This Presentation

    +
      +
    • Share my background
    • +
    • … and my approach to instruction
    • +
    • Showcase a learning object
    • +
    • … and my process for creating & assessing it
    • +
    • 30 minutes for the presentation, 15 minutes for Q & A
    • +
    + +
    +
    + +
    +

    Hello!

    +

    CWI's Instruction Coordinator & Faculty Outreach Librarian

    +

    CWI library staff won the Association of College and Research Library's 2019 Excellence in Academic Libraries award +

    + +
    +
    +

    At CWI

    +
    +
    +

    instruction room, with slide about CRAAP test and accuracy, illustrated with a gif of Merida shooting an arrow
    Inside the Library:
    Instruction Coordinator +

    +
    +
    +

    CWI's Nampa Campus Multipurpose Building, with library bookdrop in foreground
    Outside the Library:
    Faculty Outreach +

    +
    +
    + +
    +
    +

    Before CWI…

    +
    +

    Composition & Other Courses
    +

    Writing Centers
    +

    User & Space Studies
    +
    + +
    + +
    +

    Continuations

    +
    +
    +
      +
    • Agency
    • +
    • Inclusion
    • +
    • Lifelong Learning
    • +
    +
    +
    +

    set of buttons that say Libraries are for Everyone, laying on CWI branded note paper +

    +
    + +
    +
    +

    Continuations

    +
    +
    +

    Constructivist Pedagogy
    We build understanding from what we bring

    +

    Teaching for Transferability
    Reflecting on processes

    +
    +
    +

    a backpack unpacked to show tools like a map, a compass, a camera, etcPhoto by Alice Donovan Rouse via Unsplash +

    +
    + +
    +
    +
    +
    +

    CWI's Research Basics Badges

    +

    Context

    +
    +
    +

    screengrab of badges overview in Blackboard +

    +
    +
    +
      +
    • "Flipped" instruction
    • +
    • Baseline knowledge
    • +
    • Portability improves student experience
    • +
    • Nearly 45,000 badges earned between Jan. 2017—Mar. 2021
    • +
    +
    +
    + +
    +
    +

    CWI's Research Basics Badges

    +

    Content

    +
    +
    +

    screengrab of badges overview in Blackboard +

    +
    +
    +
      +
    • "Crossed the Threshold"
    • +
    • "Source Sifter" (formerly "Website Crusher")
    • +
    • "Found It!"
    • +
    • "Asked a Librarian"
    • +
    +
    +
    + +
    +
    +

    CWI's Research Basics Badges

    +

    Development

    +

    ADDIE Model

    +
      +
    • Analysis
    • +
    • Design
    • +
    • Development
    • +
    • Implementation
    • +
    • Evaluation
    • +
    +

    Angiah L. Davis. Using instructional design principles to develop effective information literacy instruction: The ADDIE model C&RL News, Vol 74, No 4, 2013.

    + +
    +
    +

    CWI's Research Basics Badges

    +

    Details

    +

    ADDIE Model

    +
      +
    • Analysis: Foundations without frustrations
    • +
    • Design: "Flipped" model & in-class activities
    • +
    • Development: Blackboard for portability
    • +
    • Implementation: Tested prototypes with library student workers
    • +
    • Evaluation: Currently emphasize summative evaluation
    • +
    +

    Angiah L. Davis. Using instructional design principles to develop effective information literacy instruction: The ADDIE model C&RL News, Vol 74, No 4, 2013.

    + +
    +
    +
    +
    +

    Source Evaluation Badge

    +

    "Website Crusher" (original version)

    +
      +
    1. Video posing the problem
    2. +
    3. Present using Wikipedia as a springboard
    4. +
    5. Present CRAAP Test as an evaluative model
    6. +
    7. Demonstrate applying the CRAAP Test
    8. +
    9. Quiz
    10. +
    + +
    +
    +

    Source Evaluation Badge

    +

    Overall Assessment Process

    +
      +
    1. IRB approved study of student learning
    2. +
    3. "Badgers" & "Non-Badgers"
    4. +
    5. Quantitative & Qualitative
    6. +
    7. Screencast of search, then "think aloud" interview
    8. +
    9. Scored selected sources according to rubric
    10. +
    11. Coded interviews according to CRAAP facets
    12. +
    + +
    +
    +

    Source Evaluation Badge

    +

    Overall Assessment Findings

    +
    Quantitative
    +
      +
    1. Some notable gains, less impact in others
    2. +
    3. Greatest increase in "Reflects awareness of library value"
    4. +
    5. "Badgers" also more likely to seek out sources through library
    6. +
    7. No distinction between "badgers" and "non-badgers" regarding source evaluation
    8. +
    + +
    +
    + +

    Source Evaluation Badge

    +

    Overall Assessment Findings

    +
    Qualitative
    +
      +
    1. Students referred to concepts like credibility or accuracy, but could not effectively apply these concepts
    2. +
    3. Students struggled to determine credibility and authority
    4. +
    5. Students seemed motivated by what "caught their eye"
    6. +
    7. CRAAP facets devolved into a "checklist" of speaking points, not practiced as an evaluation strategy
    8. +
    + +
    +
    +

    Source Evaluation Badge

    +

    Overall Assessment Paper

    +

    first page of our ACRL2021 paper

    +

    "Student Achievement Unlocked!: The Effectiveness of Badging in Community College Library Instruction" by Amanda Nida, Ryan Randall, and Kim Reed

    + +
    +
    +

    Source Evaluation Badge

    +

    Source Sifter (created in 2019)

    +

    ADDIE Model

    +
      +
    • Analysis: Source evaluation
    • +
    • Design: Researched emerging models for source evaluation, then selected Mike Caulfield's SIFT Moves
    • +
    • Development: Discussed SIFT with faculty and testing model by applying it to known sources
    • +
    • Implementation: Tested prototypes with students
    • +
    • Evaluation: Summative
    • +
    +

    Angiah L. Davis. Using + instructional design principles to develop effective information literacy instruction: The ADDIE + model C&RL News, Vol 74, No 4, 2013.

    + +
    +
    +

    Source Evaluation Badge

    +

    Source Sifter (created in 2019)

    +
    +
    +

    screencap of badge overview, including a child sifting for gold +

    +
    +
    +

    Overview of the content, describing learning outcomes and intended time to complete

    +
    +
    + +
    +
    +

    Source Evaluation Badge

    +

    Source Sifter (created in 2019)

    +
    +
    +

    screencap of our Google Slides introducing the SIFT Moves +

    +
    +
    +

    1. Google Slides introducing the SIFT Moves, a model that emphasizes lateral searching and recognizes impact of information overwhelm

    +
    +
    + +
    +
    +

    Source Evaluation Badge

    +

    Source Sifter (created in 2019)

    +
    +
    +

    screencap showing an infographic, a link to an accessible equivalent, and other text content in the badge +

    +
    +
    +

    2. Two pages with infographics:
    + a. Web Sources and Information Timeline
    + b. Web Sources: URL Suffixes

    +
    +
    + +
    + +
    +

    Source Evaluation Badge

    +

    Source Sifter (created in 2019)

    +
    +
    +

    screencap showing the page made with full text of the infographics +

    +
    +
    +

    Link to a screenreader-accessible equivalent for the infographics
    + Approach based on the DIAGRAM Center's Making Images Accessible guide for infographic accessibility

    +
    +
    + +
    + +
    +

    Source Evaluation Badge

    +

    Source Sifter (created in 2019)

    +
    +
    +

    screencap of Ryan's video introducing SIFT, with captions present +

    +
    +
    +

    3. Video demonstrating how to actually apply the SIFT Moves, starting with Google, using the Google Preview feature, using Wikipedia for lateral source evaluation, and considering consensus views of a source when forming your own evaluation

    +
    +
    + +
    + +
    +

    Source Evaluation Badge

    +

    Source Sifter (created in 2019)

    +
    +
    +

    screencap of SIFT quiz questions +

    +
    +
    +

    4. Quiz for summary evaluation, with questions targeted to misunderstandings identified during badge assessment

    +
    +
    + +
    +
    + +
    +

    Revisiting Our Goals

    +
      +
    • Share my background and instructional approach
    • +
        +
      • Agency
      • +
      • Inclusion
      • +
      • Lifelong Learning
      • +
      • Constructivist Pedagogy
      • +
      • Teaching for Transferability
      • +
      +
    • Showcase a learning object and my process for creating & assessing it
    • +
    +
    +
    +

    Sources

    +

    Angiah L. Davis. Using instructional design principles to develop effective information literacy instruction: The ADDIE model C&RL News, Vol 74, No 4, 2013.

    +

    Amanda Nida, Ryan Randall, and Kim Reed. "Student Achievement Unlocked!: The Effectiveness of Badging in Community College Library Instruction", ACRL2021 Conference Proceedings, 2021.

    + +
    +
    +

    Thank You!

    +

    finn and jake from Adventure Time hugging +

    +
    +
    +

    Any Questions?

    +
    + +
    + +
    + + + + + + + + + \ No newline at end of file diff --git a/talks/capal16.html b/talks/capal16.html new file mode 100644 index 000000000..9f26e8ac5 --- /dev/null +++ b/talks/capal16.html @@ -0,0 +1,205 @@ + + + + + + + + CAPAL16 Productive Interpretations: Encouraging Patron Agency through Cultural Criticism + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    +
    +

    Productive Interpretations

    +

    Encouraging Patron Agency through Cultural Criticism

    +
    +
    +

    Ryan P. Randall, College of Western Idaho

    +

    @foureyedsoul

    +

    If you'd like to follow along, load this in your browser: https://www.ryanpatrickrandall.com/talks/capal16.html

    + +
    +
    +

    Hello!

    +

    Map showing relationship of Boise and Calgary on map

    + +
    +
    +

    Overview

    +
    +
      +
    • Cultural studies on agency & cultural criticism
    • +
    • Traditional LIS accounts of patron agency
    • +
    • Examples of how to encourage agency
    • +
    + +
    + +
    +

    Cultural Studies & Agency

    +

    Cover of Grossberg's Bringing It All Back Home

    + +
    +
    +

    "Capitol Crawl" for the ADA

    +

    Protestors climbing U.S. Capitol building steps as a protest in favor of passing the ADA

    +

    1990 protest for Americans with Disabilities Act

    + +
    +
    +

    Washrooms

    +

    Gender Neutral Bathroom sign

    + +
    +
    +

    "Culture"

    +

    Raymond Williams cover
    Raymond Williams, Keywords: A Vocabulary of Culture and Society

    +

    Culture as practices not just elite connoisseurship

    + +
    +
    +

    Cultural Criticism

    +

    cover of Reading the Romance

    +

    Janice Radway, Reading the Romance and reader response criticism focusing on how readers use texts

    + +
    +
    +

    Critiques of Library Discourse around Agency

    +
    + + +
    + + +
    +

    Examples of Using Cultural Criticism

    +

    Vivian Harsh, director of Bronzeville library in Chicago:

    +
      +
    • Conversations with poets like Langston Hughes
    • +
    • Readers' discussion forums (more than book clubs)
    • +
    • Speakers from range of political parties
    • +
    • Collecting African artwork & material culture
    • +
    +
    +
    +

    Laura Burt's "Vivian Harsh, Adult Education, and the Library's Role as Community Center"

    + +
    +
    +

    Pedagogical orientation

    +
    +
      +
    • Problem-posing rather than banking model
    • +
    • Signage that presents a theme rather than a set
    • +
    • Investing in & displaying material collection with an eye to its pedagogical potential
    • +
    + +
    + +
    +

    Works Cited

    +
    + +
    +
    +

    Works Cited, cont.

    +
    + +
    +
    +

    Thank You!

    +

    +

    +
    +
    + +
    + + + + + + + + diff --git a/talks/comm101.html b/talks/comm101.html new file mode 100644 index 000000000..32a347349 --- /dev/null +++ b/talks/comm101.html @@ -0,0 +1,328 @@ + + + + + + + + College of Western Idaho Information Literacy and Outreach Librarian Presentation for COMM 101 Classes + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    +
    +

    COMM 101

    +

    CWI library staff won the Association of College and Research Library's 2019 Excellence in Academic Libraries award

    +

    To follow along, load this in your browser: https://www.ryanpatrickrandall.com/talks/comm101.html

    +

    Created by Ryan P. Randall

    + +
    +
    +

    Hello!

    +

    I'm Ryan Randall, from the library!

    +
    +
    +

    I'm here to help you prepare for your next assignment. And the rest of your classes, to be honest.

    + +
    +
    +
    +

    What have you already done in the library?

    + +
      +
    • Printing?
    • +
    • Used the textbooks on reserve?
    • +
    • Used one of our many computers?
    • +
    • Requested an article or book?
    • +
    • Used the online chat?
    • +
    • Used the anatomical models?
    • +
    +
    +
    +
    +

    Have your kids used the children's section?

    +

    Image of NCMP library's children's section with children's books

    +
    +
    +

    Did you come dressed up for Halloween?

    +
    +
    +
    +

    Have you used our Popular Fiction sections?

    +

    Popular Fiction book shelves

    +
    +
    +

    Here's some more library resources!

    + +
    +
    +
    +
    +

    The Information Life Cycle

    + +

    You know that sources aren't all the same.

    +

    So what makes sources different?

    +
    +
    +
    +

    Hurricane Katrina: August 2005

    +

    Satellite imagery of Hurricane Katrina hitting the shore

    +
    +
    +

    What kinds of sources might discuss Hurricane Katrina?

    +

    Where do these sources go on our timeline?

    +

    By the way, SUNY Canton has a great chart on the different "Types of Information Sources".

    +
    +
    +

    History Doesn't Repeat, But It Echoes

    +

    Let's imagine you're researching a recent event.

    +
      +
    • What does the information timeline say about the kinds of sources you could find?
    • +
    • How could you use older sources to write about new events?
    • +
    +
    +
    +

    Let's watch UNLV's "Information Life Cycle" video!

    +
    +
    +
    +
    +

    Source Evaluation & the SIFT Moves

    +
    +
    + +

    "Don't Hit Any Other Cars"

    + +
      +
    • Well-meaning advice isn't always useful. — What's a better way to help drivers learn how to drive?
    • +
    • Make the SIFT moves as natural as "look over your shoulder before you change lanes!"
    • + +
    + +
    +
    +

    SIFT Moves Help You Get Context, Fast!

    +
      +
    • Stop! — Don't waste your time reading junk.
    • +
    • Investigate the Source — Try Wikipedia. Really!
    • +
    • Find better coverage — Are these "facts" also in the news sections of the NY Times, the Associated Press, the Guardian, CNN, or other reputable venues?
    • +
    • Trace claims, quotes, and media back to the original context — CWI Library can help you find original sources. So can Google Scholar!
    • +
    +
    +
    +
    +
    +

    Source Selection & the CRAAP Criteria

    +
    +
    +

    CRAAP test criteria

    +
      +
    • Currency
    • +
    • Relevance
    • +
    • Authority
    • +
    • Accuracy
    • +
    • Purpose
    • +
    +


    Blakeslee, S. (2004). The CRAAP test.

    + +
    +
    +

    Not a "Test"—It's Guidelines

    +

    Captain Barbossa saying 'The code is more what you call guidelines than actual rules'

    +

    The CRAAP criteria help you choose where to place your time & trust. There is no simple litmus test.

    +
    +
    +

    Currency

    +

    man hanging from clocktower clock face

    +
      + +
    • When was this source published?
    • +
    • The timeframe of some information is crucial.
    • +
    + +

    +

    +
    +
    +

    Relevance

    +

    multiple 'why?'s written on chalkboard

    +
      + +
    • Why is this right for this assignment?
    • +
    • Are its approach and depth suitable for your purposes?
    • +
      +
    + +
    +
    +

    Authority

    +

    Carmen Sandiego

    +
      + +
    • Who wrote this?
    • +
    • Do they have appropriate expertise on this subject?
    • +
      +
    + +
    +
    +

    Accuracy

    +

    Merida shooting a bullseye with an arrow

    +
      + +
    • How does this source support its claims?
    • +
    • Can you check where the authors got their facts & examples?
    • +
      +
    + +
    +
    +

    Purpose

    +

    File label that says 'purpose'

    +
      + +
    • Why was this written?
    • +
    • Is the author trying to benefit personally from this?
    • +
      +
    + +
    +
    +

    CRAAP test criteria

    +
      +
    • Currency
    • +
    • Relevance
    • +
    • Authority
    • +
    • Accuracy
    • +
    • Purpose
    • +
    +


    Blakeslee, S. (2004). The CRAAP test.

    + +
    +
    +
    +
    +

    COMM 101 Research Guide

    +

    Here's some great places to start!

    + + +
    +
    +

    CWI Library Databases

    +

    Even better than Google Scholar!

    +
      +
    • Focus on disciplines taught at CWI
    • +
    • Provides access to whole source
    • +
    • Authoritative
    • +
    + +
    +
    +
    +

    How did this go? Let me know at https://bit.ly/cwilif!

    +
    + +
    +

    Keep in touch with the CWI Library

    +
    +

    Please schedule an appointment with a CWI Librarian if you'd like further research assistance.

    +

    You can also get help from the College of Western Idaho Libraries through our online chat, our FAQ pages, calling or texting us, and email!

    +
    +

    Thank you for your time!
    + "Pulling a book off the shelf" photo by Bennington College's Crossett Library with a CC BY-NC-SA 2.0 license.
    + Caulfield, Mike. SIFT (The Four Moves). Retrieved from SIFT (The Four Moves).
    + Blakeslee, S. (2004). The CRAAP test. LOEX Quarterly, 31(3), 6-7. Retrieved from https://commons.emich.edu/loexquarterly/vol31/iss3/4/.
    + "Purpose" photo by Seth Sawyers with a CC BY 2.0 license and given some minimal filtering by Ryan.

    +
    + + +
    +
    + +
    +
    + + + + + + + + diff --git a/talks/css/print/paper.css b/talks/css/print/paper.css new file mode 100755 index 000000000..27d19dd2c --- /dev/null +++ b/talks/css/print/paper.css @@ -0,0 +1,203 @@ +/* Default Print Stylesheet Template + by Rob Glazebrook of CSSnewbie.com + Last Updated: June 4, 2008 + + Feel free (nay, compelled) to edit, append, and + manipulate this file as you see fit. */ + + +@media print { + + /* SECTION 1: Set default width, margin, float, and + background. This prevents elements from extending + beyond the edge of the printed page, and prevents + unnecessary background images from printing */ + html { + background: #fff; + width: auto; + height: auto; + overflow: visible; + } + body { + background: #fff; + font-size: 20pt; + width: auto; + height: auto; + border: 0; + margin: 0 5%; + padding: 0; + overflow: visible; + float: none !important; + } + + /* SECTION 2: Remove any elements not needed in print. + This would include navigation, ads, sidebars, etc. */ + .nestedarrow, + .controls, + .fork-reveal, + .share-reveal, + .state-background, + .reveal .progress, + .reveal .backgrounds, + .reveal .slide-number { + display: none !important; + } + + /* SECTION 3: Set body font face, size, and color. + Consider using a serif font for readability. */ + body, p, td, li, div { + font-size: 20pt!important; + font-family: Georgia, "Times New Roman", Times, serif !important; + color: #000; + } + + /* SECTION 4: Set heading font face, sizes, and color. + Differentiate your headings from your body text. + Perhaps use a large sans-serif for distinction. */ + h1,h2,h3,h4,h5,h6 { + color: #000!important; + height: auto; + line-height: normal; + font-family: Georgia, "Times New Roman", Times, serif !important; + text-shadow: 0 0 0 #000 !important; + text-align: left; + letter-spacing: normal; + } + /* Need to reduce the size of the fonts for printing */ + h1 { font-size: 28pt !important; } + h2 { font-size: 24pt !important; } + h3 { font-size: 22pt !important; } + h4 { font-size: 22pt !important; font-variant: small-caps; } + h5 { font-size: 21pt !important; } + h6 { font-size: 20pt !important; font-style: italic; } + + /* SECTION 5: Make hyperlinks more usable. + Ensure links are underlined, and consider appending + the URL to the end of the link for usability. */ + a:link, + a:visited { + color: #000 !important; + font-weight: bold; + text-decoration: underline; + } + /* + .reveal a:link:after, + .reveal a:visited:after { + content: " (" attr(href) ") "; + color: #222 !important; + font-size: 90%; + } + */ + + + /* SECTION 6: more reveal.js specific additions by @skypanther */ + ul, ol, div, p { + visibility: visible; + position: static; + width: auto; + height: auto; + display: block; + overflow: visible; + margin: 0; + text-align: left !important; + } + .reveal pre, + .reveal table { + margin-left: 0; + margin-right: 0; + } + .reveal pre code { + padding: 20px; + border: 1px solid #ddd; + } + .reveal blockquote { + margin: 20px 0; + } + .reveal .slides { + position: static !important; + width: auto !important; + height: auto !important; + + left: 0 !important; + top: 0 !important; + margin-left: 0 !important; + margin-top: 0 !important; + padding: 0 !important; + zoom: 1 !important; + + overflow: visible !important; + display: block !important; + + text-align: left !important; + -webkit-perspective: none; + -moz-perspective: none; + -ms-perspective: none; + perspective: none; + + -webkit-perspective-origin: 50% 50%; + -moz-perspective-origin: 50% 50%; + -ms-perspective-origin: 50% 50%; + perspective-origin: 50% 50%; + } + .reveal .slides section { + visibility: visible !important; + position: static !important; + width: auto !important; + height: auto !important; + display: block !important; + overflow: visible !important; + + left: 0 !important; + top: 0 !important; + margin-left: 0 !important; + margin-top: 0 !important; + padding: 60px 20px !important; + z-index: auto !important; + + opacity: 1 !important; + + page-break-after: always !important; + + -webkit-transform-style: flat !important; + -moz-transform-style: flat !important; + -ms-transform-style: flat !important; + transform-style: flat !important; + + -webkit-transform: none !important; + -moz-transform: none !important; + -ms-transform: none !important; + transform: none !important; + + -webkit-transition: none !important; + -moz-transition: none !important; + -ms-transition: none !important; + transition: none !important; + } + .reveal .slides section.stack { + padding: 0 !important; + } + .reveal section:last-of-type { + page-break-after: avoid !important; + } + .reveal section .fragment { + opacity: 1 !important; + visibility: visible !important; + + -webkit-transform: none !important; + -moz-transform: none !important; + -ms-transform: none !important; + transform: none !important; + } + .reveal section img { + display: block; + margin: 15px 0px; + background: rgba(255,255,255,1); + border: 1px solid #666; + box-shadow: none; + } + + .reveal section small { + font-size: 0.8em; + } + +} diff --git a/talks/css/print/pdf.css b/talks/css/print/pdf.css new file mode 100755 index 000000000..752d9554c --- /dev/null +++ b/talks/css/print/pdf.css @@ -0,0 +1,164 @@ +/** + * This stylesheet is used to print reveal.js + * presentations to PDF. + * + * https://github.com/hakimel/reveal.js#pdf-export + */ + +* { + -webkit-print-color-adjust: exact; +} + +body { + margin: 0 auto !important; + border: 0; + padding: 0; + float: none !important; + overflow: visible; +} + +html { + width: 100%; + height: 100%; + overflow: visible; +} + +/* Remove any elements not needed in print. */ +.nestedarrow, +.reveal .controls, +.reveal .progress, +.reveal .playback, +.reveal.overview, +.fork-reveal, +.share-reveal, +.state-background { + display: none !important; +} + +h1, h2, h3, h4, h5, h6 { + text-shadow: 0 0 0 #000 !important; +} + +.reveal pre code { + overflow: hidden !important; + font-family: Courier, 'Courier New', monospace !important; +} + +ul, ol, div, p { + visibility: visible; + position: static; + width: auto; + height: auto; + display: block; + overflow: visible; + margin: auto; +} +.reveal { + width: auto !important; + height: auto !important; + overflow: hidden !important; +} +.reveal .slides { + position: static; + width: 100% !important; + height: auto !important; + zoom: 1 !important; + + left: auto; + top: auto; + margin: 0 !important; + padding: 0 !important; + + overflow: visible; + display: block; + + perspective: none; + perspective-origin: 50% 50%; +} + +.reveal .slides .pdf-page { + position: relative; + overflow: hidden; + z-index: 1; + + page-break-after: always; +} + +.reveal .slides section { + visibility: visible !important; + display: block !important; + position: absolute !important; + + margin: 0 !important; + padding: 0 !important; + box-sizing: border-box !important; + min-height: 1px; + + opacity: 1 !important; + + transform-style: flat !important; + transform: none !important; +} + +.reveal section.stack { + position: relative !important; + margin: 0 !important; + padding: 0 !important; + page-break-after: avoid !important; + height: auto !important; + min-height: auto !important; +} + +.reveal img { + box-shadow: none; +} + +.reveal .roll { + overflow: visible; + line-height: 1em; +} + +/* Slide backgrounds are placed inside of their slide when exporting to PDF */ +.reveal .slide-background { + display: block !important; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: auto !important; +} + +/* Display slide speaker notes when 'showNotes' is enabled */ +.reveal.show-notes { + max-width: none; + max-height: none; +} +.reveal .speaker-notes-pdf { + display: block; + width: 100%; + height: auto; + max-height: none; + top: auto; + right: auto; + bottom: auto; + left: auto; + z-index: 100; +} + +/* Layout option which makes notes appear on a separate page */ +.reveal .speaker-notes-pdf[data-layout="separate-page"] { + position: relative; + color: inherit; + background-color: transparent; + padding: 20px; + page-break-after: always; + border: 0; +} + +/* Display slide numbers when 'slideNumber' is enabled */ +.reveal .slide-number-pdf { + display: block; + position: absolute; + font-size: 14px; +} diff --git a/talks/css/reset.css b/talks/css/reset.css new file mode 100755 index 000000000..e2385390f --- /dev/null +++ b/talks/css/reset.css @@ -0,0 +1,30 @@ +/* http://meyerweb.com/eric/tools/css/reset/ + v4.0 | 20180602 + License: none (public domain) +*/ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +main, menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, main, menu, nav, section { + display: block; +} \ No newline at end of file diff --git a/talks/css/reveal.css b/talks/css/reveal.css new file mode 100755 index 000000000..1b9651b58 --- /dev/null +++ b/talks/css/reveal.css @@ -0,0 +1,1598 @@ +/*! + * reveal.js + * http://revealjs.com + * MIT licensed + * + * Copyright (C) 2019 Hakim El Hattab, http://hakim.se + */ +/********************************************* + * GLOBAL STYLES + *********************************************/ +html { + width: 100%; + height: 100%; + height: 100vh; + height: calc( var(--vh, 1vh) * 100); + overflow: hidden; } + +body { + height: 100%; + overflow: hidden; + position: relative; + line-height: 1; + margin: 0; + background-color: #fff; + color: #000; } + +/********************************************* + * VIEW FRAGMENTS + *********************************************/ +.reveal .slides section .fragment { + opacity: 0; + visibility: hidden; + transition: all .2s ease; } + .reveal .slides section .fragment.visible { + opacity: 1; + visibility: inherit; } + +.reveal .slides section .fragment.grow { + opacity: 1; + visibility: inherit; } + .reveal .slides section .fragment.grow.visible { + -webkit-transform: scale(1.3); + transform: scale(1.3); } + +.reveal .slides section .fragment.shrink { + opacity: 1; + visibility: inherit; } + .reveal .slides section .fragment.shrink.visible { + -webkit-transform: scale(0.7); + transform: scale(0.7); } + +.reveal .slides section .fragment.zoom-in { + -webkit-transform: scale(0.1); + transform: scale(0.1); } + .reveal .slides section .fragment.zoom-in.visible { + -webkit-transform: none; + transform: none; } + +.reveal .slides section .fragment.fade-out { + opacity: 1; + visibility: inherit; } + .reveal .slides section .fragment.fade-out.visible { + opacity: 0; + visibility: hidden; } + +.reveal .slides section .fragment.semi-fade-out { + opacity: 1; + visibility: inherit; } + .reveal .slides section .fragment.semi-fade-out.visible { + opacity: 0.5; + visibility: inherit; } + +.reveal .slides section .fragment.strike { + opacity: 1; + visibility: inherit; } + .reveal .slides section .fragment.strike.visible { + text-decoration: line-through; } + +.reveal .slides section .fragment.fade-up { + -webkit-transform: translate(0, 20%); + transform: translate(0, 20%); } + .reveal .slides section .fragment.fade-up.visible { + -webkit-transform: translate(0, 0); + transform: translate(0, 0); } + +.reveal .slides section .fragment.fade-down { + -webkit-transform: translate(0, -20%); + transform: translate(0, -20%); } + .reveal .slides section .fragment.fade-down.visible { + -webkit-transform: translate(0, 0); + transform: translate(0, 0); } + +.reveal .slides section .fragment.fade-right { + -webkit-transform: translate(-20%, 0); + transform: translate(-20%, 0); } + .reveal .slides section .fragment.fade-right.visible { + -webkit-transform: translate(0, 0); + transform: translate(0, 0); } + +.reveal .slides section .fragment.fade-left { + -webkit-transform: translate(20%, 0); + transform: translate(20%, 0); } + .reveal .slides section .fragment.fade-left.visible { + -webkit-transform: translate(0, 0); + transform: translate(0, 0); } + +.reveal .slides section .fragment.fade-in-then-out, +.reveal .slides section .fragment.current-visible { + opacity: 0; + visibility: hidden; } + .reveal .slides section .fragment.fade-in-then-out.current-fragment, + .reveal .slides section .fragment.current-visible.current-fragment { + opacity: 1; + visibility: inherit; } + +.reveal .slides section .fragment.fade-in-then-semi-out { + opacity: 0; + visibility: hidden; } + .reveal .slides section .fragment.fade-in-then-semi-out.visible { + opacity: 0.5; + visibility: inherit; } + .reveal .slides section .fragment.fade-in-then-semi-out.current-fragment { + opacity: 1; + visibility: inherit; } + +.reveal .slides section .fragment.highlight-red, +.reveal .slides section .fragment.highlight-current-red, +.reveal .slides section .fragment.highlight-green, +.reveal .slides section .fragment.highlight-current-green, +.reveal .slides section .fragment.highlight-blue, +.reveal .slides section .fragment.highlight-current-blue { + opacity: 1; + visibility: inherit; } + +.reveal .slides section .fragment.highlight-red.visible { + color: #ff2c2d; } + +.reveal .slides section .fragment.highlight-green.visible { + color: #17ff2e; } + +.reveal .slides section .fragment.highlight-blue.visible { + color: #1b91ff; } + +.reveal .slides section .fragment.highlight-current-red.current-fragment { + color: #ff2c2d; } + +.reveal .slides section .fragment.highlight-current-green.current-fragment { + color: #17ff2e; } + +.reveal .slides section .fragment.highlight-current-blue.current-fragment { + color: #1b91ff; } + +/********************************************* + * DEFAULT ELEMENT STYLES + *********************************************/ +/* Fixes issue in Chrome where italic fonts did not appear when printing to PDF */ +.reveal:after { + content: ''; + font-style: italic; } + +.reveal iframe { + z-index: 1; } + +/** Prevents layering issues in certain browser/transition combinations */ +.reveal a { + position: relative; } + +.reveal .stretch { + max-width: none; + max-height: none; } + +.reveal pre.stretch code { + height: 100%; + max-height: 100%; + box-sizing: border-box; } + +/********************************************* + * CONTROLS + *********************************************/ +@-webkit-keyframes bounce-right { + 0%, 10%, 25%, 40%, 50% { + -webkit-transform: translateX(0); + transform: translateX(0); } + 20% { + -webkit-transform: translateX(10px); + transform: translateX(10px); } + 30% { + -webkit-transform: translateX(-5px); + transform: translateX(-5px); } } +@keyframes bounce-right { + 0%, 10%, 25%, 40%, 50% { + -webkit-transform: translateX(0); + transform: translateX(0); } + 20% { + -webkit-transform: translateX(10px); + transform: translateX(10px); } + 30% { + -webkit-transform: translateX(-5px); + transform: translateX(-5px); } } + +@-webkit-keyframes bounce-down { + 0%, 10%, 25%, 40%, 50% { + -webkit-transform: translateY(0); + transform: translateY(0); } + 20% { + -webkit-transform: translateY(10px); + transform: translateY(10px); } + 30% { + -webkit-transform: translateY(-5px); + transform: translateY(-5px); } } + +@keyframes bounce-down { + 0%, 10%, 25%, 40%, 50% { + -webkit-transform: translateY(0); + transform: translateY(0); } + 20% { + -webkit-transform: translateY(10px); + transform: translateY(10px); } + 30% { + -webkit-transform: translateY(-5px); + transform: translateY(-5px); } } + +.reveal .controls { + display: none; + position: absolute; + top: auto; + bottom: 12px; + right: 12px; + left: auto; + z-index: 1; + color: #000; + pointer-events: none; + font-size: 10px; } + .reveal .controls button { + position: absolute; + padding: 0; + background-color: transparent; + border: 0; + outline: 0; + cursor: pointer; + color: currentColor; + -webkit-transform: scale(0.9999); + transform: scale(0.9999); + transition: color 0.2s ease, opacity 0.2s ease, -webkit-transform 0.2s ease; + transition: color 0.2s ease, opacity 0.2s ease, transform 0.2s ease; + z-index: 2; + pointer-events: auto; + font-size: inherit; + visibility: hidden; + opacity: 0; + -webkit-appearance: none; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } + .reveal .controls .controls-arrow:before, + .reveal .controls .controls-arrow:after { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 2.6em; + height: 0.5em; + border-radius: 0.25em; + background-color: currentColor; + transition: all 0.15s ease, background-color 0.8s ease; + -webkit-transform-origin: 0.2em 50%; + transform-origin: 0.2em 50%; + will-change: transform; } + .reveal .controls .controls-arrow { + position: relative; + width: 3.6em; + height: 3.6em; } + .reveal .controls .controls-arrow:before { + -webkit-transform: translateX(0.5em) translateY(1.55em) rotate(45deg); + transform: translateX(0.5em) translateY(1.55em) rotate(45deg); } + .reveal .controls .controls-arrow:after { + -webkit-transform: translateX(0.5em) translateY(1.55em) rotate(-45deg); + transform: translateX(0.5em) translateY(1.55em) rotate(-45deg); } + .reveal .controls .controls-arrow:hover:before { + -webkit-transform: translateX(0.5em) translateY(1.55em) rotate(40deg); + transform: translateX(0.5em) translateY(1.55em) rotate(40deg); } + .reveal .controls .controls-arrow:hover:after { + -webkit-transform: translateX(0.5em) translateY(1.55em) rotate(-40deg); + transform: translateX(0.5em) translateY(1.55em) rotate(-40deg); } + .reveal .controls .controls-arrow:active:before { + -webkit-transform: translateX(0.5em) translateY(1.55em) rotate(36deg); + transform: translateX(0.5em) translateY(1.55em) rotate(36deg); } + .reveal .controls .controls-arrow:active:after { + -webkit-transform: translateX(0.5em) translateY(1.55em) rotate(-36deg); + transform: translateX(0.5em) translateY(1.55em) rotate(-36deg); } + .reveal .controls .navigate-left { + right: 6.4em; + bottom: 3.2em; + -webkit-transform: translateX(-10px); + transform: translateX(-10px); } + .reveal .controls .navigate-right { + right: 0; + bottom: 3.2em; + -webkit-transform: translateX(10px); + transform: translateX(10px); } + .reveal .controls .navigate-right .controls-arrow { + -webkit-transform: rotate(180deg); + transform: rotate(180deg); } + .reveal .controls .navigate-right.highlight { + -webkit-animation: bounce-right 2s 50 both ease-out; + animation: bounce-right 2s 50 both ease-out; } + .reveal .controls .navigate-up { + right: 3.2em; + bottom: 6.4em; + -webkit-transform: translateY(-10px); + transform: translateY(-10px); } + .reveal .controls .navigate-up .controls-arrow { + -webkit-transform: rotate(90deg); + transform: rotate(90deg); } + .reveal .controls .navigate-down { + right: 3.2em; + bottom: 0; + -webkit-transform: translateY(10px); + transform: translateY(10px); } + .reveal .controls .navigate-down .controls-arrow { + -webkit-transform: rotate(-90deg); + transform: rotate(-90deg); } + .reveal .controls .navigate-down.highlight { + -webkit-animation: bounce-down 2s 50 both ease-out; + animation: bounce-down 2s 50 both ease-out; } + .reveal .controls[data-controls-back-arrows="faded"] .navigate-left.enabled, + .reveal .controls[data-controls-back-arrows="faded"] .navigate-up.enabled { + opacity: 0.3; } + .reveal .controls[data-controls-back-arrows="faded"] .navigate-left.enabled:hover, + .reveal .controls[data-controls-back-arrows="faded"] .navigate-up.enabled:hover { + opacity: 1; } + .reveal .controls[data-controls-back-arrows="hidden"] .navigate-left.enabled, + .reveal .controls[data-controls-back-arrows="hidden"] .navigate-up.enabled { + opacity: 0; + visibility: hidden; } + .reveal .controls .enabled { + visibility: visible; + opacity: 0.9; + cursor: pointer; + -webkit-transform: none; + transform: none; } + .reveal .controls .enabled.fragmented { + opacity: 0.5; } + .reveal .controls .enabled:hover, + .reveal .controls .enabled.fragmented:hover { + opacity: 1; } + +.reveal[data-navigation-mode="linear"].has-horizontal-slides .navigate-up, +.reveal[data-navigation-mode="linear"].has-horizontal-slides .navigate-down { + display: none; } + +.reveal[data-navigation-mode="linear"].has-horizontal-slides .navigate-left, +.reveal:not(.has-vertical-slides) .controls .navigate-left { + bottom: 1.4em; + right: 5.5em; } + +.reveal[data-navigation-mode="linear"].has-horizontal-slides .navigate-right, +.reveal:not(.has-vertical-slides) .controls .navigate-right { + bottom: 1.4em; + right: 0.5em; } + +.reveal:not(.has-horizontal-slides) .controls .navigate-up { + right: 1.4em; + bottom: 5em; } + +.reveal:not(.has-horizontal-slides) .controls .navigate-down { + right: 1.4em; + bottom: 0.5em; } + +.reveal.has-dark-background .controls { + color: #fff; } + +.reveal.has-light-background .controls { + color: #000; } + +.reveal.no-hover .controls .controls-arrow:hover:before, +.reveal.no-hover .controls .controls-arrow:active:before { + -webkit-transform: translateX(0.5em) translateY(1.55em) rotate(45deg); + transform: translateX(0.5em) translateY(1.55em) rotate(45deg); } + +.reveal.no-hover .controls .controls-arrow:hover:after, +.reveal.no-hover .controls .controls-arrow:active:after { + -webkit-transform: translateX(0.5em) translateY(1.55em) rotate(-45deg); + transform: translateX(0.5em) translateY(1.55em) rotate(-45deg); } + +@media screen and (min-width: 500px) { + .reveal .controls[data-controls-layout="edges"] { + top: 0; + right: 0; + bottom: 0; + left: 0; } + .reveal .controls[data-controls-layout="edges"] .navigate-left, + .reveal .controls[data-controls-layout="edges"] .navigate-right, + .reveal .controls[data-controls-layout="edges"] .navigate-up, + .reveal .controls[data-controls-layout="edges"] .navigate-down { + bottom: auto; + right: auto; } + .reveal .controls[data-controls-layout="edges"] .navigate-left { + top: 50%; + left: 8px; + margin-top: -1.8em; } + .reveal .controls[data-controls-layout="edges"] .navigate-right { + top: 50%; + right: 8px; + margin-top: -1.8em; } + .reveal .controls[data-controls-layout="edges"] .navigate-up { + top: 8px; + left: 50%; + margin-left: -1.8em; } + .reveal .controls[data-controls-layout="edges"] .navigate-down { + bottom: 8px; + left: 50%; + margin-left: -1.8em; } } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + position: absolute; + display: none; + height: 3px; + width: 100%; + bottom: 0; + left: 0; + z-index: 10; + background-color: rgba(0, 0, 0, 0.2); + color: #fff; } + +.reveal .progress:after { + content: ''; + display: block; + position: absolute; + height: 10px; + width: 100%; + top: -10px; } + +.reveal .progress span { + display: block; + height: 100%; + width: 0px; + background-color: currentColor; + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +/********************************************* + * SLIDE NUMBER + *********************************************/ +.reveal .slide-number { + position: absolute; + display: block; + right: 8px; + bottom: 8px; + z-index: 31; + font-family: Helvetica, sans-serif; + font-size: 12px; + line-height: 1; + color: #fff; + background-color: rgba(0, 0, 0, 0.4); + padding: 5px; } + +.reveal .slide-number a { + color: currentColor; } + +.reveal .slide-number-delimiter { + margin: 0 3px; } + +/********************************************* + * SLIDES + *********************************************/ +.reveal { + position: relative; + width: 100%; + height: 100%; + overflow: hidden; + -ms-touch-action: pinch-zoom; + touch-action: pinch-zoom; } + +.reveal .slides { + position: absolute; + width: 100%; + height: 100%; + top: 0; + right: 0; + bottom: 0; + left: 0; + margin: auto; + pointer-events: none; + overflow: visible; + z-index: 1; + text-align: center; + -webkit-perspective: 600px; + perspective: 600px; + -webkit-perspective-origin: 50% 40%; + perspective-origin: 50% 40%; } + +.reveal .slides > section { + -webkit-perspective: 600px; + perspective: 600px; } + +.reveal .slides > section, +.reveal .slides > section > section { + display: none; + position: absolute; + width: 100%; + padding: 20px 0px; + pointer-events: auto; + z-index: 10; + -webkit-transform-style: flat; + transform-style: flat; + transition: -webkit-transform-origin 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), -webkit-transform 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), visibility 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), opacity 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: transform-origin 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), transform 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), visibility 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), opacity 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +/* Global transition speed settings */ +.reveal[data-transition-speed="fast"] .slides section { + transition-duration: 400ms; } + +.reveal[data-transition-speed="slow"] .slides section { + transition-duration: 1200ms; } + +/* Slide-specific transition speed overrides */ +.reveal .slides section[data-transition-speed="fast"] { + transition-duration: 400ms; } + +.reveal .slides section[data-transition-speed="slow"] { + transition-duration: 1200ms; } + +.reveal .slides > section.stack { + padding-top: 0; + padding-bottom: 0; + pointer-events: none; + height: 100%; } + +.reveal .slides > section.present, +.reveal .slides > section > section.present { + display: block; + z-index: 11; + opacity: 1; } + +.reveal .slides > section:empty, +.reveal .slides > section > section:empty, +.reveal .slides > section[data-background-interactive], +.reveal .slides > section > section[data-background-interactive] { + pointer-events: none; } + +.reveal.center, +.reveal.center .slides, +.reveal.center .slides section { + min-height: 0 !important; } + +/* Don't allow interaction with invisible slides */ +.reveal .slides > section.future, +.reveal .slides > section > section.future, +.reveal .slides > section.past, +.reveal .slides > section > section.past { + pointer-events: none; } + +.reveal.overview .slides > section, +.reveal.overview .slides > section > section { + pointer-events: auto; } + +.reveal .slides > section.past, +.reveal .slides > section.future, +.reveal .slides > section > section.past, +.reveal .slides > section > section.future { + opacity: 0; } + +/********************************************* + * Mixins for readability of transitions + *********************************************/ +/********************************************* + * SLIDE TRANSITION + * Aliased 'linear' for backwards compatibility + *********************************************/ +.reveal.slide section { + -webkit-backface-visibility: hidden; + backface-visibility: hidden; } + +.reveal .slides > section[data-transition=slide].past, +.reveal .slides > section[data-transition~=slide-out].past, +.reveal.slide .slides > section:not([data-transition]).past { + -webkit-transform: translate(-150%, 0); + transform: translate(-150%, 0); } + +.reveal .slides > section[data-transition=slide].future, +.reveal .slides > section[data-transition~=slide-in].future, +.reveal.slide .slides > section:not([data-transition]).future { + -webkit-transform: translate(150%, 0); + transform: translate(150%, 0); } + +.reveal .slides > section > section[data-transition=slide].past, +.reveal .slides > section > section[data-transition~=slide-out].past, +.reveal.slide .slides > section > section:not([data-transition]).past { + -webkit-transform: translate(0, -150%); + transform: translate(0, -150%); } + +.reveal .slides > section > section[data-transition=slide].future, +.reveal .slides > section > section[data-transition~=slide-in].future, +.reveal.slide .slides > section > section:not([data-transition]).future { + -webkit-transform: translate(0, 150%); + transform: translate(0, 150%); } + +.reveal.linear section { + -webkit-backface-visibility: hidden; + backface-visibility: hidden; } + +.reveal .slides > section[data-transition=linear].past, +.reveal .slides > section[data-transition~=linear-out].past, +.reveal.linear .slides > section:not([data-transition]).past { + -webkit-transform: translate(-150%, 0); + transform: translate(-150%, 0); } + +.reveal .slides > section[data-transition=linear].future, +.reveal .slides > section[data-transition~=linear-in].future, +.reveal.linear .slides > section:not([data-transition]).future { + -webkit-transform: translate(150%, 0); + transform: translate(150%, 0); } + +.reveal .slides > section > section[data-transition=linear].past, +.reveal .slides > section > section[data-transition~=linear-out].past, +.reveal.linear .slides > section > section:not([data-transition]).past { + -webkit-transform: translate(0, -150%); + transform: translate(0, -150%); } + +.reveal .slides > section > section[data-transition=linear].future, +.reveal .slides > section > section[data-transition~=linear-in].future, +.reveal.linear .slides > section > section:not([data-transition]).future { + -webkit-transform: translate(0, 150%); + transform: translate(0, 150%); } + +/********************************************* + * CONVEX TRANSITION + * Aliased 'default' for backwards compatibility + *********************************************/ +.reveal .slides section[data-transition=default].stack, +.reveal.default .slides section.stack { + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; } + +.reveal .slides > section[data-transition=default].past, +.reveal .slides > section[data-transition~=default-out].past, +.reveal.default .slides > section:not([data-transition]).past { + -webkit-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0); } + +.reveal .slides > section[data-transition=default].future, +.reveal .slides > section[data-transition~=default-in].future, +.reveal.default .slides > section:not([data-transition]).future { + -webkit-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0); } + +.reveal .slides > section > section[data-transition=default].past, +.reveal .slides > section > section[data-transition~=default-out].past, +.reveal.default .slides > section > section:not([data-transition]).past { + -webkit-transform: translate3d(0, -300px, 0) rotateX(70deg) translate3d(0, -300px, 0); + transform: translate3d(0, -300px, 0) rotateX(70deg) translate3d(0, -300px, 0); } + +.reveal .slides > section > section[data-transition=default].future, +.reveal .slides > section > section[data-transition~=default-in].future, +.reveal.default .slides > section > section:not([data-transition]).future { + -webkit-transform: translate3d(0, 300px, 0) rotateX(-70deg) translate3d(0, 300px, 0); + transform: translate3d(0, 300px, 0) rotateX(-70deg) translate3d(0, 300px, 0); } + +.reveal .slides section[data-transition=convex].stack, +.reveal.convex .slides section.stack { + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; } + +.reveal .slides > section[data-transition=convex].past, +.reveal .slides > section[data-transition~=convex-out].past, +.reveal.convex .slides > section:not([data-transition]).past { + -webkit-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0); } + +.reveal .slides > section[data-transition=convex].future, +.reveal .slides > section[data-transition~=convex-in].future, +.reveal.convex .slides > section:not([data-transition]).future { + -webkit-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0); } + +.reveal .slides > section > section[data-transition=convex].past, +.reveal .slides > section > section[data-transition~=convex-out].past, +.reveal.convex .slides > section > section:not([data-transition]).past { + -webkit-transform: translate3d(0, -300px, 0) rotateX(70deg) translate3d(0, -300px, 0); + transform: translate3d(0, -300px, 0) rotateX(70deg) translate3d(0, -300px, 0); } + +.reveal .slides > section > section[data-transition=convex].future, +.reveal .slides > section > section[data-transition~=convex-in].future, +.reveal.convex .slides > section > section:not([data-transition]).future { + -webkit-transform: translate3d(0, 300px, 0) rotateX(-70deg) translate3d(0, 300px, 0); + transform: translate3d(0, 300px, 0) rotateX(-70deg) translate3d(0, 300px, 0); } + +/********************************************* + * CONCAVE TRANSITION + *********************************************/ +.reveal .slides section[data-transition=concave].stack, +.reveal.concave .slides section.stack { + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; } + +.reveal .slides > section[data-transition=concave].past, +.reveal .slides > section[data-transition~=concave-out].past, +.reveal.concave .slides > section:not([data-transition]).past { + -webkit-transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0); } + +.reveal .slides > section[data-transition=concave].future, +.reveal .slides > section[data-transition~=concave-in].future, +.reveal.concave .slides > section:not([data-transition]).future { + -webkit-transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0); } + +.reveal .slides > section > section[data-transition=concave].past, +.reveal .slides > section > section[data-transition~=concave-out].past, +.reveal.concave .slides > section > section:not([data-transition]).past { + -webkit-transform: translate3d(0, -80%, 0) rotateX(-70deg) translate3d(0, -80%, 0); + transform: translate3d(0, -80%, 0) rotateX(-70deg) translate3d(0, -80%, 0); } + +.reveal .slides > section > section[data-transition=concave].future, +.reveal .slides > section > section[data-transition~=concave-in].future, +.reveal.concave .slides > section > section:not([data-transition]).future { + -webkit-transform: translate3d(0, 80%, 0) rotateX(70deg) translate3d(0, 80%, 0); + transform: translate3d(0, 80%, 0) rotateX(70deg) translate3d(0, 80%, 0); } + +/********************************************* + * ZOOM TRANSITION + *********************************************/ +.reveal .slides section[data-transition=zoom], +.reveal.zoom .slides section:not([data-transition]) { + transition-timing-function: ease; } + +.reveal .slides > section[data-transition=zoom].past, +.reveal .slides > section[data-transition~=zoom-out].past, +.reveal.zoom .slides > section:not([data-transition]).past { + visibility: hidden; + -webkit-transform: scale(16); + transform: scale(16); } + +.reveal .slides > section[data-transition=zoom].future, +.reveal .slides > section[data-transition~=zoom-in].future, +.reveal.zoom .slides > section:not([data-transition]).future { + visibility: hidden; + -webkit-transform: scale(0.2); + transform: scale(0.2); } + +.reveal .slides > section > section[data-transition=zoom].past, +.reveal .slides > section > section[data-transition~=zoom-out].past, +.reveal.zoom .slides > section > section:not([data-transition]).past { + -webkit-transform: scale(16); + transform: scale(16); } + +.reveal .slides > section > section[data-transition=zoom].future, +.reveal .slides > section > section[data-transition~=zoom-in].future, +.reveal.zoom .slides > section > section:not([data-transition]).future { + -webkit-transform: scale(0.2); + transform: scale(0.2); } + +/********************************************* + * CUBE TRANSITION + * + * WARNING: + * this is deprecated and will be removed in a + * future version. + *********************************************/ +.reveal.cube .slides { + -webkit-perspective: 1300px; + perspective: 1300px; } + +.reveal.cube .slides section { + padding: 30px; + min-height: 700px; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + box-sizing: border-box; + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; } + +.reveal.center.cube .slides section { + min-height: 0; } + +.reveal.cube .slides section:not(.stack):before { + content: ''; + position: absolute; + display: block; + width: 100%; + height: 100%; + left: 0; + top: 0; + background: rgba(0, 0, 0, 0.1); + border-radius: 4px; + -webkit-transform: translateZ(-20px); + transform: translateZ(-20px); } + +.reveal.cube .slides section:not(.stack):after { + content: ''; + position: absolute; + display: block; + width: 90%; + height: 30px; + left: 5%; + bottom: 0; + background: none; + z-index: 1; + border-radius: 4px; + box-shadow: 0px 95px 25px rgba(0, 0, 0, 0.2); + -webkit-transform: translateZ(-90px) rotateX(65deg); + transform: translateZ(-90px) rotateX(65deg); } + +.reveal.cube .slides > section.stack { + padding: 0; + background: none; } + +.reveal.cube .slides > section.past { + -webkit-transform-origin: 100% 0%; + transform-origin: 100% 0%; + -webkit-transform: translate3d(-100%, 0, 0) rotateY(-90deg); + transform: translate3d(-100%, 0, 0) rotateY(-90deg); } + +.reveal.cube .slides > section.future { + -webkit-transform-origin: 0% 0%; + transform-origin: 0% 0%; + -webkit-transform: translate3d(100%, 0, 0) rotateY(90deg); + transform: translate3d(100%, 0, 0) rotateY(90deg); } + +.reveal.cube .slides > section > section.past { + -webkit-transform-origin: 0% 100%; + transform-origin: 0% 100%; + -webkit-transform: translate3d(0, -100%, 0) rotateX(90deg); + transform: translate3d(0, -100%, 0) rotateX(90deg); } + +.reveal.cube .slides > section > section.future { + -webkit-transform-origin: 0% 0%; + transform-origin: 0% 0%; + -webkit-transform: translate3d(0, 100%, 0) rotateX(-90deg); + transform: translate3d(0, 100%, 0) rotateX(-90deg); } + +/********************************************* + * PAGE TRANSITION + * + * WARNING: + * this is deprecated and will be removed in a + * future version. + *********************************************/ +.reveal.page .slides { + -webkit-perspective-origin: 0% 50%; + perspective-origin: 0% 50%; + -webkit-perspective: 3000px; + perspective: 3000px; } + +.reveal.page .slides section { + padding: 30px; + min-height: 700px; + box-sizing: border-box; + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; } + +.reveal.page .slides section.past { + z-index: 12; } + +.reveal.page .slides section:not(.stack):before { + content: ''; + position: absolute; + display: block; + width: 100%; + height: 100%; + left: 0; + top: 0; + background: rgba(0, 0, 0, 0.1); + -webkit-transform: translateZ(-20px); + transform: translateZ(-20px); } + +.reveal.page .slides section:not(.stack):after { + content: ''; + position: absolute; + display: block; + width: 90%; + height: 30px; + left: 5%; + bottom: 0; + background: none; + z-index: 1; + border-radius: 4px; + box-shadow: 0px 95px 25px rgba(0, 0, 0, 0.2); + -webkit-transform: translateZ(-90px) rotateX(65deg); } + +.reveal.page .slides > section.stack { + padding: 0; + background: none; } + +.reveal.page .slides > section.past { + -webkit-transform-origin: 0% 0%; + transform-origin: 0% 0%; + -webkit-transform: translate3d(-40%, 0, 0) rotateY(-80deg); + transform: translate3d(-40%, 0, 0) rotateY(-80deg); } + +.reveal.page .slides > section.future { + -webkit-transform-origin: 100% 0%; + transform-origin: 100% 0%; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); } + +.reveal.page .slides > section > section.past { + -webkit-transform-origin: 0% 0%; + transform-origin: 0% 0%; + -webkit-transform: translate3d(0, -40%, 0) rotateX(80deg); + transform: translate3d(0, -40%, 0) rotateX(80deg); } + +.reveal.page .slides > section > section.future { + -webkit-transform-origin: 0% 100%; + transform-origin: 0% 100%; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); } + +/********************************************* + * FADE TRANSITION + *********************************************/ +.reveal .slides section[data-transition=fade], +.reveal.fade .slides section:not([data-transition]), +.reveal.fade .slides > section > section:not([data-transition]) { + -webkit-transform: none; + transform: none; + transition: opacity 0.5s; } + +.reveal.fade.overview .slides section, +.reveal.fade.overview .slides > section > section { + transition: none; } + +/********************************************* + * NO TRANSITION + *********************************************/ +.reveal .slides section[data-transition=none], +.reveal.none .slides section:not([data-transition]) { + -webkit-transform: none; + transform: none; + transition: none; } + +/********************************************* + * PAUSED MODE + *********************************************/ +.reveal .pause-overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: black; + visibility: hidden; + opacity: 0; + z-index: 100; + transition: all 1s ease; } + +.reveal .pause-overlay .resume-button { + position: absolute; + bottom: 20px; + right: 20px; + color: #ccc; + border-radius: 2px; + padding: 6px 14px; + border: 2px solid #ccc; + font-size: 16px; + background: transparent; + cursor: pointer; } + .reveal .pause-overlay .resume-button:hover { + color: #fff; + border-color: #fff; } + +.reveal.paused .pause-overlay { + visibility: visible; + opacity: 1; } + +/********************************************* + * FALLBACK + *********************************************/ +.no-transforms { + overflow-y: auto; } + +.no-transforms .reveal { + overflow: visible; } + +.no-transforms .reveal .slides { + position: relative; + width: 80%; + max-width: 1280px; + height: auto; + top: 0; + margin: 0 auto; + text-align: center; } + +.no-transforms .reveal .controls, +.no-transforms .reveal .progress { + display: none; } + +.no-transforms .reveal .slides section { + display: block; + opacity: 1; + position: relative; + height: auto; + min-height: 0; + top: 0; + left: 0; + margin: 10vh 0; + margin: 70px 0; + -webkit-transform: none; + transform: none; } + +.reveal .no-transition, +.reveal .no-transition * { + transition: none !important; } + +/********************************************* + * PER-SLIDE BACKGROUNDS + *********************************************/ +.reveal .backgrounds { + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + -webkit-perspective: 600px; + perspective: 600px; } + +.reveal .slide-background { + display: none; + position: absolute; + width: 100%; + height: 100%; + opacity: 0; + visibility: hidden; + overflow: hidden; + background-color: rgba(0, 0, 0, 0); + transition: all 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +.reveal .slide-background-content { + position: absolute; + width: 100%; + height: 100%; + background-position: 50% 50%; + background-repeat: no-repeat; + background-size: cover; } + +.reveal .slide-background.stack { + display: block; } + +.reveal .slide-background.present { + opacity: 1; + visibility: visible; + z-index: 2; } + +.print-pdf .reveal .slide-background { + opacity: 1 !important; + visibility: visible !important; } + +/* Video backgrounds */ +.reveal .slide-background video { + position: absolute; + width: 100%; + height: 100%; + max-width: none; + max-height: none; + top: 0; + left: 0; + -o-object-fit: cover; + object-fit: cover; } + +.reveal .slide-background[data-background-size="contain"] video { + -o-object-fit: contain; + object-fit: contain; } + +/* Immediate transition style */ +.reveal[data-background-transition=none] > .backgrounds .slide-background, +.reveal > .backgrounds .slide-background[data-background-transition=none] { + transition: none; } + +/* Slide */ +.reveal[data-background-transition=slide] > .backgrounds .slide-background, +.reveal > .backgrounds .slide-background[data-background-transition=slide] { + opacity: 1; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; } + +.reveal[data-background-transition=slide] > .backgrounds .slide-background.past, +.reveal > .backgrounds .slide-background.past[data-background-transition=slide] { + -webkit-transform: translate(-100%, 0); + transform: translate(-100%, 0); } + +.reveal[data-background-transition=slide] > .backgrounds .slide-background.future, +.reveal > .backgrounds .slide-background.future[data-background-transition=slide] { + -webkit-transform: translate(100%, 0); + transform: translate(100%, 0); } + +.reveal[data-background-transition=slide] > .backgrounds .slide-background > .slide-background.past, +.reveal > .backgrounds .slide-background > .slide-background.past[data-background-transition=slide] { + -webkit-transform: translate(0, -100%); + transform: translate(0, -100%); } + +.reveal[data-background-transition=slide] > .backgrounds .slide-background > .slide-background.future, +.reveal > .backgrounds .slide-background > .slide-background.future[data-background-transition=slide] { + -webkit-transform: translate(0, 100%); + transform: translate(0, 100%); } + +/* Convex */ +.reveal[data-background-transition=convex] > .backgrounds .slide-background.past, +.reveal > .backgrounds .slide-background.past[data-background-transition=convex] { + opacity: 0; + -webkit-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0); } + +.reveal[data-background-transition=convex] > .backgrounds .slide-background.future, +.reveal > .backgrounds .slide-background.future[data-background-transition=convex] { + opacity: 0; + -webkit-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0); } + +.reveal[data-background-transition=convex] > .backgrounds .slide-background > .slide-background.past, +.reveal > .backgrounds .slide-background > .slide-background.past[data-background-transition=convex] { + opacity: 0; + -webkit-transform: translate3d(0, -100%, 0) rotateX(90deg) translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0) rotateX(90deg) translate3d(0, -100%, 0); } + +.reveal[data-background-transition=convex] > .backgrounds .slide-background > .slide-background.future, +.reveal > .backgrounds .slide-background > .slide-background.future[data-background-transition=convex] { + opacity: 0; + -webkit-transform: translate3d(0, 100%, 0) rotateX(-90deg) translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0) rotateX(-90deg) translate3d(0, 100%, 0); } + +/* Concave */ +.reveal[data-background-transition=concave] > .backgrounds .slide-background.past, +.reveal > .backgrounds .slide-background.past[data-background-transition=concave] { + opacity: 0; + -webkit-transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0); } + +.reveal[data-background-transition=concave] > .backgrounds .slide-background.future, +.reveal > .backgrounds .slide-background.future[data-background-transition=concave] { + opacity: 0; + -webkit-transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0); } + +.reveal[data-background-transition=concave] > .backgrounds .slide-background > .slide-background.past, +.reveal > .backgrounds .slide-background > .slide-background.past[data-background-transition=concave] { + opacity: 0; + -webkit-transform: translate3d(0, -100%, 0) rotateX(-90deg) translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0) rotateX(-90deg) translate3d(0, -100%, 0); } + +.reveal[data-background-transition=concave] > .backgrounds .slide-background > .slide-background.future, +.reveal > .backgrounds .slide-background > .slide-background.future[data-background-transition=concave] { + opacity: 0; + -webkit-transform: translate3d(0, 100%, 0) rotateX(90deg) translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0) rotateX(90deg) translate3d(0, 100%, 0); } + +/* Zoom */ +.reveal[data-background-transition=zoom] > .backgrounds .slide-background, +.reveal > .backgrounds .slide-background[data-background-transition=zoom] { + transition-timing-function: ease; } + +.reveal[data-background-transition=zoom] > .backgrounds .slide-background.past, +.reveal > .backgrounds .slide-background.past[data-background-transition=zoom] { + opacity: 0; + visibility: hidden; + -webkit-transform: scale(16); + transform: scale(16); } + +.reveal[data-background-transition=zoom] > .backgrounds .slide-background.future, +.reveal > .backgrounds .slide-background.future[data-background-transition=zoom] { + opacity: 0; + visibility: hidden; + -webkit-transform: scale(0.2); + transform: scale(0.2); } + +.reveal[data-background-transition=zoom] > .backgrounds .slide-background > .slide-background.past, +.reveal > .backgrounds .slide-background > .slide-background.past[data-background-transition=zoom] { + opacity: 0; + visibility: hidden; + -webkit-transform: scale(16); + transform: scale(16); } + +.reveal[data-background-transition=zoom] > .backgrounds .slide-background > .slide-background.future, +.reveal > .backgrounds .slide-background > .slide-background.future[data-background-transition=zoom] { + opacity: 0; + visibility: hidden; + -webkit-transform: scale(0.2); + transform: scale(0.2); } + +/* Global transition speed settings */ +.reveal[data-transition-speed="fast"] > .backgrounds .slide-background { + transition-duration: 400ms; } + +.reveal[data-transition-speed="slow"] > .backgrounds .slide-background { + transition-duration: 1200ms; } + +/********************************************* + * OVERVIEW + *********************************************/ +.reveal.overview { + -webkit-perspective-origin: 50% 50%; + perspective-origin: 50% 50%; + -webkit-perspective: 700px; + perspective: 700px; } + .reveal.overview .slides { + -moz-transform-style: preserve-3d; } + .reveal.overview .slides section { + height: 100%; + top: 0 !important; + opacity: 1 !important; + overflow: hidden; + visibility: visible !important; + cursor: pointer; + box-sizing: border-box; } + .reveal.overview .slides section:hover, + .reveal.overview .slides section.present { + outline: 10px solid rgba(150, 150, 150, 0.4); + outline-offset: 10px; } + .reveal.overview .slides section .fragment { + opacity: 1; + transition: none; } + .reveal.overview .slides section:after, + .reveal.overview .slides section:before { + display: none !important; } + .reveal.overview .slides > section.stack { + padding: 0; + top: 0 !important; + background: none; + outline: none; + overflow: visible; } + .reveal.overview .backgrounds { + -webkit-perspective: inherit; + perspective: inherit; + -moz-transform-style: preserve-3d; } + .reveal.overview .backgrounds .slide-background { + opacity: 1; + visibility: visible; + outline: 10px solid rgba(150, 150, 150, 0.1); + outline-offset: 10px; } + .reveal.overview .backgrounds .slide-background.stack { + overflow: visible; } + +.reveal.overview .slides section, +.reveal.overview-deactivating .slides section { + transition: none; } + +.reveal.overview .backgrounds .slide-background, +.reveal.overview-deactivating .backgrounds .slide-background { + transition: none; } + +/********************************************* + * RTL SUPPORT + *********************************************/ +.reveal.rtl .slides, +.reveal.rtl .slides h1, +.reveal.rtl .slides h2, +.reveal.rtl .slides h3, +.reveal.rtl .slides h4, +.reveal.rtl .slides h5, +.reveal.rtl .slides h6 { + direction: rtl; + font-family: sans-serif; } + +.reveal.rtl pre, +.reveal.rtl code { + direction: ltr; } + +.reveal.rtl ol, +.reveal.rtl ul { + text-align: right; } + +.reveal.rtl .progress span { + float: right; } + +/********************************************* + * PARALLAX BACKGROUND + *********************************************/ +.reveal.has-parallax-background .backgrounds { + transition: all 0.8s ease; } + +/* Global transition speed settings */ +.reveal.has-parallax-background[data-transition-speed="fast"] .backgrounds { + transition-duration: 400ms; } + +.reveal.has-parallax-background[data-transition-speed="slow"] .backgrounds { + transition-duration: 1200ms; } + +/********************************************* + * OVERLAY FOR LINK PREVIEWS AND HELP + *********************************************/ +.reveal > .overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 1000; + background: rgba(0, 0, 0, 0.9); + opacity: 0; + visibility: hidden; + transition: all 0.3s ease; } + +.reveal > .overlay.visible { + opacity: 1; + visibility: visible; } + +.reveal > .overlay .spinner { + position: absolute; + display: block; + top: 50%; + left: 50%; + width: 32px; + height: 32px; + margin: -16px 0 0 -16px; + z-index: 10; + background-image: url(data:image/gif;base64,R0lGODlhIAAgAPMAAJmZmf%2F%2F%2F6%2Bvr8nJybW1tcDAwOjo6Nvb26ioqKOjo7Ozs%2FLy8vz8%2FAAAAAAAAAAAACH%2FC05FVFNDQVBFMi4wAwEAAAAh%2FhpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh%2BQQJCgAAACwAAAAAIAAgAAAE5xDISWlhperN52JLhSSdRgwVo1ICQZRUsiwHpTJT4iowNS8vyW2icCF6k8HMMBkCEDskxTBDAZwuAkkqIfxIQyhBQBFvAQSDITM5VDW6XNE4KagNh6Bgwe60smQUB3d4Rz1ZBApnFASDd0hihh12BkE9kjAJVlycXIg7CQIFA6SlnJ87paqbSKiKoqusnbMdmDC2tXQlkUhziYtyWTxIfy6BE8WJt5YJvpJivxNaGmLHT0VnOgSYf0dZXS7APdpB309RnHOG5gDqXGLDaC457D1zZ%2FV%2FnmOM82XiHRLYKhKP1oZmADdEAAAh%2BQQJCgAAACwAAAAAIAAgAAAE6hDISWlZpOrNp1lGNRSdRpDUolIGw5RUYhhHukqFu8DsrEyqnWThGvAmhVlteBvojpTDDBUEIFwMFBRAmBkSgOrBFZogCASwBDEY%2FCZSg7GSE0gSCjQBMVG023xWBhklAnoEdhQEfyNqMIcKjhRsjEdnezB%2BA4k8gTwJhFuiW4dokXiloUepBAp5qaKpp6%2BHo7aWW54wl7obvEe0kRuoplCGepwSx2jJvqHEmGt6whJpGpfJCHmOoNHKaHx61WiSR92E4lbFoq%2BB6QDtuetcaBPnW6%2BO7wDHpIiK9SaVK5GgV543tzjgGcghAgAh%2BQQJCgAAACwAAAAAIAAgAAAE7hDISSkxpOrN5zFHNWRdhSiVoVLHspRUMoyUakyEe8PTPCATW9A14E0UvuAKMNAZKYUZCiBMuBakSQKG8G2FzUWox2AUtAQFcBKlVQoLgQReZhQlCIJesQXI5B0CBnUMOxMCenoCfTCEWBsJColTMANldx15BGs8B5wlCZ9Po6OJkwmRpnqkqnuSrayqfKmqpLajoiW5HJq7FL1Gr2mMMcKUMIiJgIemy7xZtJsTmsM4xHiKv5KMCXqfyUCJEonXPN2rAOIAmsfB3uPoAK%2B%2BG%2Bw48edZPK%2BM6hLJpQg484enXIdQFSS1u6UhksENEQAAIfkECQoAAAAsAAAAACAAIAAABOcQyEmpGKLqzWcZRVUQnZYg1aBSh2GUVEIQ2aQOE%2BG%2BcD4ntpWkZQj1JIiZIogDFFyHI0UxQwFugMSOFIPJftfVAEoZLBbcLEFhlQiqGp1Vd140AUklUN3eCA51C1EWMzMCezCBBmkxVIVHBWd3HHl9JQOIJSdSnJ0TDKChCwUJjoWMPaGqDKannasMo6WnM562R5YluZRwur0wpgqZE7NKUm%2BFNRPIhjBJxKZteWuIBMN4zRMIVIhffcgojwCF117i4nlLnY5ztRLsnOk%2BaV%2BoJY7V7m76PdkS4trKcdg0Zc0tTcKkRAAAIfkECQoAAAAsAAAAACAAIAAABO4QyEkpKqjqzScpRaVkXZWQEximw1BSCUEIlDohrft6cpKCk5xid5MNJTaAIkekKGQkWyKHkvhKsR7ARmitkAYDYRIbUQRQjWBwJRzChi9CRlBcY1UN4g0%2FVNB0AlcvcAYHRyZPdEQFYV8ccwR5HWxEJ02YmRMLnJ1xCYp0Y5idpQuhopmmC2KgojKasUQDk5BNAwwMOh2RtRq5uQuPZKGIJQIGwAwGf6I0JXMpC8C7kXWDBINFMxS4DKMAWVWAGYsAdNqW5uaRxkSKJOZKaU3tPOBZ4DuK2LATgJhkPJMgTwKCdFjyPHEnKxFCDhEAACH5BAkKAAAALAAAAAAgACAAAATzEMhJaVKp6s2nIkolIJ2WkBShpkVRWqqQrhLSEu9MZJKK9y1ZrqYK9WiClmvoUaF8gIQSNeF1Er4MNFn4SRSDARWroAIETg1iVwuHjYB1kYc1mwruwXKC9gmsJXliGxc%2BXiUCby9ydh1sOSdMkpMTBpaXBzsfhoc5l58Gm5yToAaZhaOUqjkDgCWNHAULCwOLaTmzswadEqggQwgHuQsHIoZCHQMMQgQGubVEcxOPFAcMDAYUA85eWARmfSRQCdcMe0zeP1AAygwLlJtPNAAL19DARdPzBOWSm1brJBi45soRAWQAAkrQIykShQ9wVhHCwCQCACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiRMDjI0Fd30%2FiI2UA5GSS5UDj2l6NoqgOgN4gksEBgYFf0FDqKgHnyZ9OX8HrgYHdHpcHQULXAS2qKpENRg7eAMLC7kTBaixUYFkKAzWAAnLC7FLVxLWDBLKCwaKTULgEwbLA4hJtOkSBNqITT3xEgfLpBtzE%2FjiuL04RGEBgwWhShRgQExHBAAh%2BQQJCgAAACwAAAAAIAAgAAAE7xDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfZiCqGk5dTESJeaOAlClzsJsqwiJwiqnFrb2nS9kmIcgEsjQydLiIlHehhpejaIjzh9eomSjZR%2BipslWIRLAgMDOR2DOqKogTB9pCUJBagDBXR6XB0EBkIIsaRsGGMMAxoDBgYHTKJiUYEGDAzHC9EACcUGkIgFzgwZ0QsSBcXHiQvOwgDdEwfFs0sDzt4S6BK4xYjkDOzn0unFeBzOBijIm1Dgmg5YFQwsCMjp1oJ8LyIAACH5BAkKAAAALAAAAAAgACAAAATwEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GGl6NoiPOH16iZKNlH6KmyWFOggHhEEvAwwMA0N9GBsEC6amhnVcEwavDAazGwIDaH1ipaYLBUTCGgQDA8NdHz0FpqgTBwsLqAbWAAnIA4FWKdMLGdYGEgraigbT0OITBcg5QwPT4xLrROZL6AuQAPUS7bxLpoWidY0JtxLHKhwwMJBTHgPKdEQAACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GAULDJCRiXo1CpGXDJOUjY%2BYip9DhToJA4RBLwMLCwVDfRgbBAaqqoZ1XBMHswsHtxtFaH1iqaoGNgAIxRpbFAgfPQSqpbgGBqUD1wBXeCYp1AYZ19JJOYgH1KwA4UBvQwXUBxPqVD9L3sbp2BNk2xvvFPJd%2BMFCN6HAAIKgNggY0KtEBAAh%2BQQJCgAAACwAAAAAIAAgAAAE6BDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfYIDMaAFdTESJeaEDAIMxYFqrOUaNW4E4ObYcCXaiBVEgULe0NJaxxtYksjh2NLkZISgDgJhHthkpU4mW6blRiYmZOlh4JWkDqILwUGBnE6TYEbCgevr0N1gH4At7gHiRpFaLNrrq8HNgAJA70AWxQIH1%2BvsYMDAzZQPC9VCNkDWUhGkuE5PxJNwiUK4UfLzOlD4WvzAHaoG9nxPi5d%2BjYUqfAhhykOFwJWiAAAIfkECQoAAAAsAAAAACAAIAAABPAQyElpUqnqzaciSoVkXVUMFaFSwlpOCcMYlErAavhOMnNLNo8KsZsMZItJEIDIFSkLGQoQTNhIsFehRww2CQLKF0tYGKYSg%2BygsZIuNqJksKgbfgIGepNo2cIUB3V1B3IvNiBYNQaDSTtfhhx0CwVPI0UJe0%2Bbm4g5VgcGoqOcnjmjqDSdnhgEoamcsZuXO1aWQy8KAwOAuTYYGwi7w5h%2BKr0SJ8MFihpNbx%2B4Erq7BYBuzsdiH1jCAzoSfl0rVirNbRXlBBlLX%2BBP0XJLAPGzTkAuAOqb0WT5AH7OcdCm5B8TgRwSRKIHQtaLCwg1RAAAOwAAAAAAAAAAAA%3D%3D); + visibility: visible; + opacity: 0.6; + transition: all 0.3s ease; } + +.reveal > .overlay header { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 40px; + z-index: 2; + border-bottom: 1px solid #222; } + +.reveal > .overlay header a { + display: inline-block; + width: 40px; + height: 40px; + line-height: 36px; + padding: 0 10px; + float: right; + opacity: 0.6; + box-sizing: border-box; } + +.reveal > .overlay header a:hover { + opacity: 1; } + +.reveal > .overlay header a .icon { + display: inline-block; + width: 20px; + height: 20px; + background-position: 50% 50%; + background-size: 100%; + background-repeat: no-repeat; } + +.reveal > .overlay header a.close .icon { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABkklEQVRYR8WX4VHDMAxG6wnoJrABZQPYBCaBTWAD2g1gE5gg6OOsXuxIlr40d81dfrSJ9V4c2VLK7spHuTJ/5wpM07QXuXc5X0opX2tEJcadjHuV80li/FgxTIEK/5QBCICBD6xEhSMGHgQPgBgLiYVAB1dpSqKDawxTohFw4JSEA3clzgIBPCURwE2JucBR7rhPJJv5OpJwDX+SfDjgx1wACQeJG1aChP9K/IMmdZ8DtESV1WyP3Bt4MwM6sj4NMxMYiqUWHQu4KYA/SYkIjOsm3BXYWMKFDwU2khjCQ4ELJUJ4SmClRArOCmSXGuKma0fYD5CbzHxFpCSGAhfAVSSUGDUk2BWZaff2g6GE15BsBQ9nwmpIGDiyHQddwNTMKkbZaf9fajXQca1EX44puJZUsnY0ObGmITE3GVLCbEhQUjGVt146j6oasWN+49Vph2w1pZ5EansNZqKBm1txbU57iRRcZ86RWMDdWtBJUHBHwoQPi1GV+JCbntmvok7iTX4/Up9mgyTc/FJYDTcndgH/AA5A/CHsyEkVAAAAAElFTkSuQmCC); } + +.reveal > .overlay header a.external .icon { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAcElEQVRYR+2WSQoAIQwEzf8f7XiOMkUQxUPlGkM3hVmiQfQR9GYnH1SsAQlI4DiBqkCMoNb9y2e90IAEJPAcgdznU9+engMaeJ7Azh5Y1U67gAho4DqBqmB1buAf0MB1AlVBek83ZPkmJMGc1wAR+AAqod/B97TRpQAAAABJRU5ErkJggg==); } + +.reveal > .overlay .viewport { + position: absolute; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + top: 40px; + right: 0; + bottom: 0; + left: 0; } + +.reveal > .overlay.overlay-preview .viewport iframe { + width: 100%; + height: 100%; + max-width: 100%; + max-height: 100%; + border: 0; + opacity: 0; + visibility: hidden; + transition: all 0.3s ease; } + +.reveal > .overlay.overlay-preview.loaded .viewport iframe { + opacity: 1; + visibility: visible; } + +.reveal > .overlay.overlay-preview.loaded .viewport-inner { + position: absolute; + z-index: -1; + left: 0; + top: 45%; + width: 100%; + text-align: center; + letter-spacing: normal; } + +.reveal > .overlay.overlay-preview .x-frame-error { + opacity: 0; + transition: opacity 0.3s ease 0.3s; } + +.reveal > .overlay.overlay-preview.loaded .x-frame-error { + opacity: 1; } + +.reveal > .overlay.overlay-preview.loaded .spinner { + opacity: 0; + visibility: hidden; + -webkit-transform: scale(0.2); + transform: scale(0.2); } + +.reveal > .overlay.overlay-help .viewport { + overflow: auto; + color: #fff; } + +.reveal > .overlay.overlay-help .viewport .viewport-inner { + width: 600px; + margin: auto; + padding: 20px 20px 80px 20px; + text-align: center; + letter-spacing: normal; } + +.reveal > .overlay.overlay-help .viewport .viewport-inner .title { + font-size: 20px; } + +.reveal > .overlay.overlay-help .viewport .viewport-inner table { + border: 1px solid #fff; + border-collapse: collapse; + font-size: 16px; } + +.reveal > .overlay.overlay-help .viewport .viewport-inner table th, +.reveal > .overlay.overlay-help .viewport .viewport-inner table td { + width: 200px; + padding: 14px; + border: 1px solid #fff; + vertical-align: middle; } + +.reveal > .overlay.overlay-help .viewport .viewport-inner table th { + padding-top: 20px; + padding-bottom: 20px; } + +/********************************************* + * PLAYBACK COMPONENT + *********************************************/ +.reveal .playback { + position: absolute; + left: 15px; + bottom: 20px; + z-index: 30; + cursor: pointer; + transition: all 400ms ease; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } + +.reveal.overview .playback { + opacity: 0; + visibility: hidden; } + +/********************************************* + * CODE HIGHLGIHTING + *********************************************/ +.reveal .hljs table { + margin: initial; } + +.reveal .hljs-ln-code, +.reveal .hljs-ln-numbers { + padding: 0; + border: 0; } + +.reveal .hljs-ln-numbers { + opacity: 0.6; + padding-right: 0.75em; + text-align: right; + vertical-align: top; } + +.reveal .hljs[data-line-numbers]:not([data-line-numbers=""]) tr:not(.highlight-line) { + opacity: 0.4; } + +/********************************************* + * ROLLING LINKS + *********************************************/ +.reveal .roll { + display: inline-block; + line-height: 1.2; + overflow: hidden; + vertical-align: top; + -webkit-perspective: 400px; + perspective: 400px; + -webkit-perspective-origin: 50% 50%; + perspective-origin: 50% 50%; } + +.reveal .roll:hover { + background: none; + text-shadow: none; } + +.reveal .roll span { + display: block; + position: relative; + padding: 0 2px; + pointer-events: none; + transition: all 400ms ease; + -webkit-transform-origin: 50% 0%; + transform-origin: 50% 0%; + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; } + +.reveal .roll:hover span { + background: rgba(0, 0, 0, 0.5); + -webkit-transform: translate3d(0px, 0px, -45px) rotateX(90deg); + transform: translate3d(0px, 0px, -45px) rotateX(90deg); } + +.reveal .roll span:after { + content: attr(data-title); + display: block; + position: absolute; + left: 0; + top: 0; + padding: 0 2px; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-transform-origin: 50% 0%; + transform-origin: 50% 0%; + -webkit-transform: translate3d(0px, 110%, 0px) rotateX(-90deg); + transform: translate3d(0px, 110%, 0px) rotateX(-90deg); } + +/********************************************* + * SPEAKER NOTES + *********************************************/ +.reveal aside.notes { + display: none; } + +.reveal .speaker-notes { + display: none; + position: absolute; + width: 33.3333333333%; + height: 100%; + top: 0; + left: 100%; + padding: 14px 18px 14px 18px; + z-index: 1; + font-size: 18px; + line-height: 1.4; + border: 1px solid rgba(0, 0, 0, 0.05); + color: #222; + background-color: #f5f5f5; + overflow: auto; + box-sizing: border-box; + text-align: left; + font-family: Helvetica, sans-serif; + -webkit-overflow-scrolling: touch; } + .reveal .speaker-notes .notes-placeholder { + color: #ccc; + font-style: italic; } + .reveal .speaker-notes:focus { + outline: none; } + .reveal .speaker-notes:before { + content: 'Speaker notes'; + display: block; + margin-bottom: 10px; + opacity: 0.5; } + +.reveal.show-notes { + max-width: 75%; + overflow: visible; } + +.reveal.show-notes .speaker-notes { + display: block; } + +@media screen and (min-width: 1600px) { + .reveal .speaker-notes { + font-size: 20px; } } + +@media screen and (max-width: 1024px) { + .reveal.show-notes { + border-left: 0; + max-width: none; + max-height: 70%; + max-height: 70vh; + overflow: visible; } + .reveal.show-notes .speaker-notes { + top: 100%; + left: 0; + width: 100%; + height: 42.8571428571%; + height: 30vh; + border: 0; } } + +@media screen and (max-width: 600px) { + .reveal.show-notes { + max-height: 60%; + max-height: 60vh; } + .reveal.show-notes .speaker-notes { + top: 100%; + height: 66.6666666667%; + height: 40vh; } + .reveal .speaker-notes { + font-size: 14px; } } + +/********************************************* + * ZOOM PLUGIN + *********************************************/ +.zoomed .reveal *, +.zoomed .reveal *:before, +.zoomed .reveal *:after { + -webkit-backface-visibility: visible !important; + backface-visibility: visible !important; } + +.zoomed .reveal .progress, +.zoomed .reveal .controls { + opacity: 0; } + +.zoomed .reveal .roll span { + background: none; } + +.zoomed .reveal .roll span:after { + visibility: hidden; } diff --git a/talks/css/reveal.scss b/talks/css/reveal.scss new file mode 100755 index 000000000..ab732a461 --- /dev/null +++ b/talks/css/reveal.scss @@ -0,0 +1,1768 @@ +/*! + * reveal.js + * http://revealjs.com + * MIT licensed + * + * Copyright (C) 2019 Hakim El Hattab, http://hakim.se + */ + + +/********************************************* + * GLOBAL STYLES + *********************************************/ + +html { + width: 100%; + height: 100%; + height: 100vh; + height: calc( var(--vh, 1vh) * 100 ); + overflow: hidden; +} + +body { + height: 100%; + overflow: hidden; + position: relative; + line-height: 1; + margin: 0; + + background-color: #fff; + color: #000; +} + + +/********************************************* + * VIEW FRAGMENTS + *********************************************/ + +.reveal .slides section .fragment { + opacity: 0; + visibility: hidden; + transition: all .2s ease; + + &.visible { + opacity: 1; + visibility: inherit; + } +} + +.reveal .slides section .fragment.grow { + opacity: 1; + visibility: inherit; + + &.visible { + transform: scale( 1.3 ); + } +} + +.reveal .slides section .fragment.shrink { + opacity: 1; + visibility: inherit; + + &.visible { + transform: scale( 0.7 ); + } +} + +.reveal .slides section .fragment.zoom-in { + transform: scale( 0.1 ); + + &.visible { + transform: none; + } +} + +.reveal .slides section .fragment.fade-out { + opacity: 1; + visibility: inherit; + + &.visible { + opacity: 0; + visibility: hidden; + } +} + +.reveal .slides section .fragment.semi-fade-out { + opacity: 1; + visibility: inherit; + + &.visible { + opacity: 0.5; + visibility: inherit; + } +} + +.reveal .slides section .fragment.strike { + opacity: 1; + visibility: inherit; + + &.visible { + text-decoration: line-through; + } +} + +.reveal .slides section .fragment.fade-up { + transform: translate(0, 20%); + + &.visible { + transform: translate(0, 0); + } +} + +.reveal .slides section .fragment.fade-down { + transform: translate(0, -20%); + + &.visible { + transform: translate(0, 0); + } +} + +.reveal .slides section .fragment.fade-right { + transform: translate(-20%, 0); + + &.visible { + transform: translate(0, 0); + } +} + +.reveal .slides section .fragment.fade-left { + transform: translate(20%, 0); + + &.visible { + transform: translate(0, 0); + } +} + +.reveal .slides section .fragment.fade-in-then-out, +.reveal .slides section .fragment.current-visible { + opacity: 0; + visibility: hidden; + + &.current-fragment { + opacity: 1; + visibility: inherit; + } +} + +.reveal .slides section .fragment.fade-in-then-semi-out { + opacity: 0; + visibility: hidden; + + &.visible { + opacity: 0.5; + visibility: inherit; + } + + &.current-fragment { + opacity: 1; + visibility: inherit; + } +} + +.reveal .slides section .fragment.highlight-red, +.reveal .slides section .fragment.highlight-current-red, +.reveal .slides section .fragment.highlight-green, +.reveal .slides section .fragment.highlight-current-green, +.reveal .slides section .fragment.highlight-blue, +.reveal .slides section .fragment.highlight-current-blue { + opacity: 1; + visibility: inherit; +} + .reveal .slides section .fragment.highlight-red.visible { + color: #ff2c2d + } + .reveal .slides section .fragment.highlight-green.visible { + color: #17ff2e; + } + .reveal .slides section .fragment.highlight-blue.visible { + color: #1b91ff; + } + +.reveal .slides section .fragment.highlight-current-red.current-fragment { + color: #ff2c2d +} +.reveal .slides section .fragment.highlight-current-green.current-fragment { + color: #17ff2e; +} +.reveal .slides section .fragment.highlight-current-blue.current-fragment { + color: #1b91ff; +} + + +/********************************************* + * DEFAULT ELEMENT STYLES + *********************************************/ + +/* Fixes issue in Chrome where italic fonts did not appear when printing to PDF */ +.reveal:after { + content: ''; + font-style: italic; +} + +.reveal iframe { + z-index: 1; +} + +/** Prevents layering issues in certain browser/transition combinations */ +.reveal a { + position: relative; +} + +.reveal .stretch { + max-width: none; + max-height: none; +} + +.reveal pre.stretch code { + height: 100%; + max-height: 100%; + box-sizing: border-box; +} + + +/********************************************* + * CONTROLS + *********************************************/ + +@keyframes bounce-right { + 0%, 10%, 25%, 40%, 50% {transform: translateX(0);} + 20% {transform: translateX(10px);} + 30% {transform: translateX(-5px);} +} + +@keyframes bounce-down { + 0%, 10%, 25%, 40%, 50% {transform: translateY(0);} + 20% {transform: translateY(10px);} + 30% {transform: translateY(-5px);} +} + +$controlArrowSize: 3.6em; +$controlArrowSpacing: 1.4em; +$controlArrowLength: 2.6em; +$controlArrowThickness: 0.5em; +$controlsArrowAngle: 45deg; +$controlsArrowAngleHover: 40deg; +$controlsArrowAngleActive: 36deg; + +@mixin controlsArrowTransform( $angle ) { + &:before { + transform: translateX(($controlArrowSize - $controlArrowLength)/2) translateY(($controlArrowSize - $controlArrowThickness)/2) rotate( $angle ); + } + + &:after { + transform: translateX(($controlArrowSize - $controlArrowLength)/2) translateY(($controlArrowSize - $controlArrowThickness)/2) rotate( -$angle ); + } +} + +.reveal .controls { + $spacing: 12px; + + display: none; + position: absolute; + top: auto; + bottom: $spacing; + right: $spacing; + left: auto; + z-index: 1; + color: #000; + pointer-events: none; + font-size: 10px; + + button { + position: absolute; + padding: 0; + background-color: transparent; + border: 0; + outline: 0; + cursor: pointer; + color: currentColor; + transform: scale(.9999); + transition: color 0.2s ease, + opacity 0.2s ease, + transform 0.2s ease; + z-index: 2; // above slides + pointer-events: auto; + font-size: inherit; + + visibility: hidden; + opacity: 0; + + -webkit-appearance: none; + -webkit-tap-highlight-color: rgba( 0, 0, 0, 0 ); + } + + .controls-arrow:before, + .controls-arrow:after { + content: ''; + position: absolute; + top: 0; + left: 0; + width: $controlArrowLength; + height: $controlArrowThickness; + border-radius: $controlArrowThickness/2; + background-color: currentColor; + + transition: all 0.15s ease, background-color 0.8s ease; + transform-origin: floor(($controlArrowThickness/2)*10)/10 50%; + will-change: transform; + } + + .controls-arrow { + position: relative; + width: $controlArrowSize; + height: $controlArrowSize; + + @include controlsArrowTransform( $controlsArrowAngle ); + + &:hover { + @include controlsArrowTransform( $controlsArrowAngleHover ); + } + + &:active { + @include controlsArrowTransform( $controlsArrowAngleActive ); + } + } + + .navigate-left { + right: $controlArrowSize + $controlArrowSpacing*2; + bottom: $controlArrowSpacing + $controlArrowSize/2; + transform: translateX( -10px ); + } + + .navigate-right { + right: 0; + bottom: $controlArrowSpacing + $controlArrowSize/2; + transform: translateX( 10px ); + + .controls-arrow { + transform: rotate( 180deg ); + } + + &.highlight { + animation: bounce-right 2s 50 both ease-out; + } + } + + .navigate-up { + right: $controlArrowSpacing + $controlArrowSize/2; + bottom: $controlArrowSpacing*2 + $controlArrowSize; + transform: translateY( -10px ); + + .controls-arrow { + transform: rotate( 90deg ); + } + } + + .navigate-down { + right: $controlArrowSpacing + $controlArrowSize/2; + bottom: 0; + transform: translateY( 10px ); + + .controls-arrow { + transform: rotate( -90deg ); + } + + &.highlight { + animation: bounce-down 2s 50 both ease-out; + } + } + + // Back arrow style: "faded": + // Deemphasize backwards navigation arrows in favor of drawing + // attention to forwards navigation + &[data-controls-back-arrows="faded"] .navigate-left.enabled, + &[data-controls-back-arrows="faded"] .navigate-up.enabled { + opacity: 0.3; + + &:hover { + opacity: 1; + } + } + + // Back arrow style: "hidden": + // Never show arrows for backwards navigation + &[data-controls-back-arrows="hidden"] .navigate-left.enabled, + &[data-controls-back-arrows="hidden"] .navigate-up.enabled { + opacity: 0; + visibility: hidden; + } + + // Any control button that can be clicked is "enabled" + .enabled { + visibility: visible; + opacity: 0.9; + cursor: pointer; + transform: none; + } + + // Any control button that leads to showing or hiding + // a fragment + .enabled.fragmented { + opacity: 0.5; + } + + .enabled:hover, + .enabled.fragmented:hover { + opacity: 1; + } +} + +.reveal[data-navigation-mode="linear"].has-horizontal-slides .navigate-up, +.reveal[data-navigation-mode="linear"].has-horizontal-slides .navigate-down { + display: none; +} + +// Adjust the layout when there are no vertical slides +.reveal[data-navigation-mode="linear"].has-horizontal-slides .navigate-left, +.reveal:not(.has-vertical-slides) .controls .navigate-left { + bottom: $controlArrowSpacing; + right: 0.5em + $controlArrowSpacing + $controlArrowSize; +} + +.reveal[data-navigation-mode="linear"].has-horizontal-slides .navigate-right, +.reveal:not(.has-vertical-slides) .controls .navigate-right { + bottom: $controlArrowSpacing; + right: 0.5em; +} + +// Adjust the layout when there are no horizontal slides +.reveal:not(.has-horizontal-slides) .controls .navigate-up { + right: $controlArrowSpacing; + bottom: $controlArrowSpacing + $controlArrowSize; +} +.reveal:not(.has-horizontal-slides) .controls .navigate-down { + right: $controlArrowSpacing; + bottom: 0.5em; +} + +// Invert arrows based on background color +.reveal.has-dark-background .controls { + color: #fff; +} +.reveal.has-light-background .controls { + color: #000; +} + +// Disable active states on touch devices +.reveal.no-hover .controls .controls-arrow:hover, +.reveal.no-hover .controls .controls-arrow:active { + @include controlsArrowTransform( $controlsArrowAngle ); +} + +// Edge aligned controls layout +@media screen and (min-width: 500px) { + + $spacing: 8px; + + .reveal .controls[data-controls-layout="edges"] { + & { + top: 0; + right: 0; + bottom: 0; + left: 0; + } + + .navigate-left, + .navigate-right, + .navigate-up, + .navigate-down { + bottom: auto; + right: auto; + } + + .navigate-left { + top: 50%; + left: $spacing; + margin-top: -$controlArrowSize/2; + } + + .navigate-right { + top: 50%; + right: $spacing; + margin-top: -$controlArrowSize/2; + } + + .navigate-up { + top: $spacing; + left: 50%; + margin-left: -$controlArrowSize/2; + } + + .navigate-down { + bottom: $spacing; + left: 50%; + margin-left: -$controlArrowSize/2; + } + } + +} + + +/********************************************* + * PROGRESS BAR + *********************************************/ + +.reveal .progress { + position: absolute; + display: none; + height: 3px; + width: 100%; + bottom: 0; + left: 0; + z-index: 10; + + background-color: rgba( 0, 0, 0, 0.2 ); + color: #fff; +} + .reveal .progress:after { + content: ''; + display: block; + position: absolute; + height: 10px; + width: 100%; + top: -10px; + } + .reveal .progress span { + display: block; + height: 100%; + width: 0px; + + background-color: currentColor; + transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985); + } + +/********************************************* + * SLIDE NUMBER + *********************************************/ + +.reveal .slide-number { + position: absolute; + display: block; + right: 8px; + bottom: 8px; + z-index: 31; + font-family: Helvetica, sans-serif; + font-size: 12px; + line-height: 1; + color: #fff; + background-color: rgba( 0, 0, 0, 0.4 ); + padding: 5px; +} + +.reveal .slide-number a { + color: currentColor; +} + +.reveal .slide-number-delimiter { + margin: 0 3px; +} + +/********************************************* + * SLIDES + *********************************************/ + +.reveal { + position: relative; + width: 100%; + height: 100%; + overflow: hidden; + touch-action: pinch-zoom; +} + +.reveal .slides { + position: absolute; + width: 100%; + height: 100%; + top: 0; + right: 0; + bottom: 0; + left: 0; + margin: auto; + pointer-events: none; + + overflow: visible; + z-index: 1; + text-align: center; + perspective: 600px; + perspective-origin: 50% 40%; +} + +.reveal .slides>section { + perspective: 600px; +} + +.reveal .slides>section, +.reveal .slides>section>section { + display: none; + position: absolute; + width: 100%; + padding: 20px 0px; + pointer-events: auto; + + z-index: 10; + transform-style: flat; + transition: transform-origin 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985), + transform 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985), + visibility 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985), + opacity 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985); +} + +/* Global transition speed settings */ +.reveal[data-transition-speed="fast"] .slides section { + transition-duration: 400ms; +} +.reveal[data-transition-speed="slow"] .slides section { + transition-duration: 1200ms; +} + +/* Slide-specific transition speed overrides */ +.reveal .slides section[data-transition-speed="fast"] { + transition-duration: 400ms; +} +.reveal .slides section[data-transition-speed="slow"] { + transition-duration: 1200ms; +} + +.reveal .slides>section.stack { + padding-top: 0; + padding-bottom: 0; + pointer-events: none; + height: 100%; +} + +.reveal .slides>section.present, +.reveal .slides>section>section.present { + display: block; + z-index: 11; + opacity: 1; +} + +.reveal .slides>section:empty, +.reveal .slides>section>section:empty, +.reveal .slides>section[data-background-interactive], +.reveal .slides>section>section[data-background-interactive] { + pointer-events: none; +} + +.reveal.center, +.reveal.center .slides, +.reveal.center .slides section { + min-height: 0 !important; +} + +/* Don't allow interaction with invisible slides */ +.reveal .slides>section.future, +.reveal .slides>section>section.future, +.reveal .slides>section.past, +.reveal .slides>section>section.past { + pointer-events: none; +} + +.reveal.overview .slides>section, +.reveal.overview .slides>section>section { + pointer-events: auto; +} + +.reveal .slides>section.past, +.reveal .slides>section.future, +.reveal .slides>section>section.past, +.reveal .slides>section>section.future { + opacity: 0; +} + + +/********************************************* + * Mixins for readability of transitions + *********************************************/ + +@mixin transition-global($style) { + .reveal .slides section[data-transition=#{$style}], + .reveal.#{$style} .slides section:not([data-transition]) { + @content; + } +} +@mixin transition-stack($style) { + .reveal .slides section[data-transition=#{$style}].stack, + .reveal.#{$style} .slides section.stack { + @content; + } +} +@mixin transition-horizontal-past($style) { + .reveal .slides>section[data-transition=#{$style}].past, + .reveal .slides>section[data-transition~=#{$style}-out].past, + .reveal.#{$style} .slides>section:not([data-transition]).past { + @content; + } +} +@mixin transition-horizontal-future($style) { + .reveal .slides>section[data-transition=#{$style}].future, + .reveal .slides>section[data-transition~=#{$style}-in].future, + .reveal.#{$style} .slides>section:not([data-transition]).future { + @content; + } +} + +@mixin transition-vertical-past($style) { + .reveal .slides>section>section[data-transition=#{$style}].past, + .reveal .slides>section>section[data-transition~=#{$style}-out].past, + .reveal.#{$style} .slides>section>section:not([data-transition]).past { + @content; + } +} +@mixin transition-vertical-future($style) { + .reveal .slides>section>section[data-transition=#{$style}].future, + .reveal .slides>section>section[data-transition~=#{$style}-in].future, + .reveal.#{$style} .slides>section>section:not([data-transition]).future { + @content; + } +} + +/********************************************* + * SLIDE TRANSITION + * Aliased 'linear' for backwards compatibility + *********************************************/ + +@each $stylename in slide, linear { + .reveal.#{$stylename} section { + backface-visibility: hidden; + } + @include transition-horizontal-past(#{$stylename}) { + transform: translate(-150%, 0); + } + @include transition-horizontal-future(#{$stylename}) { + transform: translate(150%, 0); + } + @include transition-vertical-past(#{$stylename}) { + transform: translate(0, -150%); + } + @include transition-vertical-future(#{$stylename}) { + transform: translate(0, 150%); + } +} + +/********************************************* + * CONVEX TRANSITION + * Aliased 'default' for backwards compatibility + *********************************************/ + +@each $stylename in default, convex { + @include transition-stack(#{$stylename}) { + transform-style: preserve-3d; + } + + @include transition-horizontal-past(#{$stylename}) { + transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0); + } + @include transition-horizontal-future(#{$stylename}) { + transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0); + } + @include transition-vertical-past(#{$stylename}) { + transform: translate3d(0, -300px, 0) rotateX(70deg) translate3d(0, -300px, 0); + } + @include transition-vertical-future(#{$stylename}) { + transform: translate3d(0, 300px, 0) rotateX(-70deg) translate3d(0, 300px, 0); + } +} + +/********************************************* + * CONCAVE TRANSITION + *********************************************/ + +@include transition-stack(concave) { + transform-style: preserve-3d; +} + +@include transition-horizontal-past(concave) { + transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0); +} +@include transition-horizontal-future(concave) { + transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0); +} +@include transition-vertical-past(concave) { + transform: translate3d(0, -80%, 0) rotateX(-70deg) translate3d(0, -80%, 0); +} +@include transition-vertical-future(concave) { + transform: translate3d(0, 80%, 0) rotateX(70deg) translate3d(0, 80%, 0); +} + + +/********************************************* + * ZOOM TRANSITION + *********************************************/ + +@include transition-global(zoom) { + transition-timing-function: ease; +} +@include transition-horizontal-past(zoom) { + visibility: hidden; + transform: scale(16); +} +@include transition-horizontal-future(zoom) { + visibility: hidden; + transform: scale(0.2); +} +@include transition-vertical-past(zoom) { + transform: scale(16); +} +@include transition-vertical-future(zoom) { + transform: scale(0.2); +} + + +/********************************************* + * CUBE TRANSITION + * + * WARNING: + * this is deprecated and will be removed in a + * future version. + *********************************************/ + +.reveal.cube .slides { + perspective: 1300px; +} + +.reveal.cube .slides section { + padding: 30px; + min-height: 700px; + backface-visibility: hidden; + box-sizing: border-box; + transform-style: preserve-3d; +} + .reveal.center.cube .slides section { + min-height: 0; + } + .reveal.cube .slides section:not(.stack):before { + content: ''; + position: absolute; + display: block; + width: 100%; + height: 100%; + left: 0; + top: 0; + background: rgba(0,0,0,0.1); + border-radius: 4px; + transform: translateZ( -20px ); + } + .reveal.cube .slides section:not(.stack):after { + content: ''; + position: absolute; + display: block; + width: 90%; + height: 30px; + left: 5%; + bottom: 0; + background: none; + z-index: 1; + + border-radius: 4px; + box-shadow: 0px 95px 25px rgba(0,0,0,0.2); + transform: translateZ(-90px) rotateX( 65deg ); + } + +.reveal.cube .slides>section.stack { + padding: 0; + background: none; +} + +.reveal.cube .slides>section.past { + transform-origin: 100% 0%; + transform: translate3d(-100%, 0, 0) rotateY(-90deg); +} + +.reveal.cube .slides>section.future { + transform-origin: 0% 0%; + transform: translate3d(100%, 0, 0) rotateY(90deg); +} + +.reveal.cube .slides>section>section.past { + transform-origin: 0% 100%; + transform: translate3d(0, -100%, 0) rotateX(90deg); +} + +.reveal.cube .slides>section>section.future { + transform-origin: 0% 0%; + transform: translate3d(0, 100%, 0) rotateX(-90deg); +} + + +/********************************************* + * PAGE TRANSITION + * + * WARNING: + * this is deprecated and will be removed in a + * future version. + *********************************************/ + +.reveal.page .slides { + perspective-origin: 0% 50%; + perspective: 3000px; +} + +.reveal.page .slides section { + padding: 30px; + min-height: 700px; + box-sizing: border-box; + transform-style: preserve-3d; +} + .reveal.page .slides section.past { + z-index: 12; + } + .reveal.page .slides section:not(.stack):before { + content: ''; + position: absolute; + display: block; + width: 100%; + height: 100%; + left: 0; + top: 0; + background: rgba(0,0,0,0.1); + transform: translateZ( -20px ); + } + .reveal.page .slides section:not(.stack):after { + content: ''; + position: absolute; + display: block; + width: 90%; + height: 30px; + left: 5%; + bottom: 0; + background: none; + z-index: 1; + + border-radius: 4px; + box-shadow: 0px 95px 25px rgba(0,0,0,0.2); + + -webkit-transform: translateZ(-90px) rotateX( 65deg ); + } + +.reveal.page .slides>section.stack { + padding: 0; + background: none; +} + +.reveal.page .slides>section.past { + transform-origin: 0% 0%; + transform: translate3d(-40%, 0, 0) rotateY(-80deg); +} + +.reveal.page .slides>section.future { + transform-origin: 100% 0%; + transform: translate3d(0, 0, 0); +} + +.reveal.page .slides>section>section.past { + transform-origin: 0% 0%; + transform: translate3d(0, -40%, 0) rotateX(80deg); +} + +.reveal.page .slides>section>section.future { + transform-origin: 0% 100%; + transform: translate3d(0, 0, 0); +} + + +/********************************************* + * FADE TRANSITION + *********************************************/ + +.reveal .slides section[data-transition=fade], +.reveal.fade .slides section:not([data-transition]), +.reveal.fade .slides>section>section:not([data-transition]) { + transform: none; + transition: opacity 0.5s; +} + + +.reveal.fade.overview .slides section, +.reveal.fade.overview .slides>section>section { + transition: none; +} + + +/********************************************* + * NO TRANSITION + *********************************************/ + +@include transition-global(none) { + transform: none; + transition: none; +} + + +/********************************************* + * PAUSED MODE + *********************************************/ + +.reveal .pause-overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: black; + visibility: hidden; + opacity: 0; + z-index: 100; + transition: all 1s ease; +} + +.reveal .pause-overlay .resume-button { + position: absolute; + bottom: 20px; + right: 20px; + color: #ccc; + border-radius: 2px; + padding: 6px 14px; + border: 2px solid #ccc; + font-size: 16px; + background: transparent; + cursor: pointer; + + &:hover { + color: #fff; + border-color: #fff; + } +} + +.reveal.paused .pause-overlay { + visibility: visible; + opacity: 1; +} + + +/********************************************* + * FALLBACK + *********************************************/ + +.no-transforms { + overflow-y: auto; +} + +.no-transforms .reveal { + overflow: visible; +} + +.no-transforms .reveal .slides { + position: relative; + width: 80%; + max-width: 1280px; + height: auto; + top: 0; + margin: 0 auto; + text-align: center; +} + +.no-transforms .reveal .controls, +.no-transforms .reveal .progress { + display: none; +} + +.no-transforms .reveal .slides section { + display: block; + opacity: 1; + position: relative; + height: auto; + min-height: 0; + top: 0; + left: 0; + margin: 10vh 0; + margin: 70px 0; + transform: none; +} + +.reveal .no-transition, +.reveal .no-transition * { + transition: none !important; +} + + +/********************************************* + * PER-SLIDE BACKGROUNDS + *********************************************/ + +.reveal .backgrounds { + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + perspective: 600px; +} + .reveal .slide-background { + display: none; + position: absolute; + width: 100%; + height: 100%; + opacity: 0; + visibility: hidden; + overflow: hidden; + + background-color: rgba( 0, 0, 0, 0 ); + + transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985); + } + + .reveal .slide-background-content { + position: absolute; + width: 100%; + height: 100%; + + background-position: 50% 50%; + background-repeat: no-repeat; + background-size: cover; + } + + .reveal .slide-background.stack { + display: block; + } + + .reveal .slide-background.present { + opacity: 1; + visibility: visible; + z-index: 2; + } + + .print-pdf .reveal .slide-background { + opacity: 1 !important; + visibility: visible !important; + } + +/* Video backgrounds */ +.reveal .slide-background video { + position: absolute; + width: 100%; + height: 100%; + max-width: none; + max-height: none; + top: 0; + left: 0; + object-fit: cover; +} + .reveal .slide-background[data-background-size="contain"] video { + object-fit: contain; + } + +/* Immediate transition style */ +.reveal[data-background-transition=none]>.backgrounds .slide-background, +.reveal>.backgrounds .slide-background[data-background-transition=none] { + transition: none; +} + +/* Slide */ +.reveal[data-background-transition=slide]>.backgrounds .slide-background, +.reveal>.backgrounds .slide-background[data-background-transition=slide] { + opacity: 1; + backface-visibility: hidden; +} + .reveal[data-background-transition=slide]>.backgrounds .slide-background.past, + .reveal>.backgrounds .slide-background.past[data-background-transition=slide] { + transform: translate(-100%, 0); + } + .reveal[data-background-transition=slide]>.backgrounds .slide-background.future, + .reveal>.backgrounds .slide-background.future[data-background-transition=slide] { + transform: translate(100%, 0); + } + + .reveal[data-background-transition=slide]>.backgrounds .slide-background>.slide-background.past, + .reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=slide] { + transform: translate(0, -100%); + } + .reveal[data-background-transition=slide]>.backgrounds .slide-background>.slide-background.future, + .reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=slide] { + transform: translate(0, 100%); + } + + +/* Convex */ +.reveal[data-background-transition=convex]>.backgrounds .slide-background.past, +.reveal>.backgrounds .slide-background.past[data-background-transition=convex] { + opacity: 0; + transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0); +} +.reveal[data-background-transition=convex]>.backgrounds .slide-background.future, +.reveal>.backgrounds .slide-background.future[data-background-transition=convex] { + opacity: 0; + transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0); +} + +.reveal[data-background-transition=convex]>.backgrounds .slide-background>.slide-background.past, +.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=convex] { + opacity: 0; + transform: translate3d(0, -100%, 0) rotateX(90deg) translate3d(0, -100%, 0); +} +.reveal[data-background-transition=convex]>.backgrounds .slide-background>.slide-background.future, +.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=convex] { + opacity: 0; + transform: translate3d(0, 100%, 0) rotateX(-90deg) translate3d(0, 100%, 0); +} + + +/* Concave */ +.reveal[data-background-transition=concave]>.backgrounds .slide-background.past, +.reveal>.backgrounds .slide-background.past[data-background-transition=concave] { + opacity: 0; + transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0); +} +.reveal[data-background-transition=concave]>.backgrounds .slide-background.future, +.reveal>.backgrounds .slide-background.future[data-background-transition=concave] { + opacity: 0; + transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0); +} + +.reveal[data-background-transition=concave]>.backgrounds .slide-background>.slide-background.past, +.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=concave] { + opacity: 0; + transform: translate3d(0, -100%, 0) rotateX(-90deg) translate3d(0, -100%, 0); +} +.reveal[data-background-transition=concave]>.backgrounds .slide-background>.slide-background.future, +.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=concave] { + opacity: 0; + transform: translate3d(0, 100%, 0) rotateX(90deg) translate3d(0, 100%, 0); +} + +/* Zoom */ +.reveal[data-background-transition=zoom]>.backgrounds .slide-background, +.reveal>.backgrounds .slide-background[data-background-transition=zoom] { + transition-timing-function: ease; +} + +.reveal[data-background-transition=zoom]>.backgrounds .slide-background.past, +.reveal>.backgrounds .slide-background.past[data-background-transition=zoom] { + opacity: 0; + visibility: hidden; + transform: scale(16); +} +.reveal[data-background-transition=zoom]>.backgrounds .slide-background.future, +.reveal>.backgrounds .slide-background.future[data-background-transition=zoom] { + opacity: 0; + visibility: hidden; + transform: scale(0.2); +} + +.reveal[data-background-transition=zoom]>.backgrounds .slide-background>.slide-background.past, +.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=zoom] { + opacity: 0; + visibility: hidden; + transform: scale(16); +} +.reveal[data-background-transition=zoom]>.backgrounds .slide-background>.slide-background.future, +.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=zoom] { + opacity: 0; + visibility: hidden; + transform: scale(0.2); +} + + +/* Global transition speed settings */ +.reveal[data-transition-speed="fast"]>.backgrounds .slide-background { + transition-duration: 400ms; +} +.reveal[data-transition-speed="slow"]>.backgrounds .slide-background { + transition-duration: 1200ms; +} + + +/********************************************* + * OVERVIEW + *********************************************/ + +.reveal.overview { + perspective-origin: 50% 50%; + perspective: 700px; + + .slides { + // Fixes overview rendering errors in FF48+, not applied to + // other browsers since it degrades performance + -moz-transform-style: preserve-3d; + } + + .slides section { + height: 100%; + top: 0 !important; + opacity: 1 !important; + overflow: hidden; + visibility: visible !important; + cursor: pointer; + box-sizing: border-box; + } + .slides section:hover, + .slides section.present { + outline: 10px solid rgba(150,150,150,0.4); + outline-offset: 10px; + } + .slides section .fragment { + opacity: 1; + transition: none; + } + .slides section:after, + .slides section:before { + display: none !important; + } + .slides>section.stack { + padding: 0; + top: 0 !important; + background: none; + outline: none; + overflow: visible; + } + + .backgrounds { + perspective: inherit; + + // Fixes overview rendering errors in FF48+, not applied to + // other browsers since it degrades performance + -moz-transform-style: preserve-3d; + } + + .backgrounds .slide-background { + opacity: 1; + visibility: visible; + + // This can't be applied to the slide itself in Safari + outline: 10px solid rgba(150,150,150,0.1); + outline-offset: 10px; + } + + .backgrounds .slide-background.stack { + overflow: visible; + } +} + +// Disable transitions transitions while we're activating +// or deactivating the overview mode. +.reveal.overview .slides section, +.reveal.overview-deactivating .slides section { + transition: none; +} + +.reveal.overview .backgrounds .slide-background, +.reveal.overview-deactivating .backgrounds .slide-background { + transition: none; +} + + +/********************************************* + * RTL SUPPORT + *********************************************/ + +.reveal.rtl .slides, +.reveal.rtl .slides h1, +.reveal.rtl .slides h2, +.reveal.rtl .slides h3, +.reveal.rtl .slides h4, +.reveal.rtl .slides h5, +.reveal.rtl .slides h6 { + direction: rtl; + font-family: sans-serif; +} + +.reveal.rtl pre, +.reveal.rtl code { + direction: ltr; +} + +.reveal.rtl ol, +.reveal.rtl ul { + text-align: right; +} + +.reveal.rtl .progress span { + float: right +} + +/********************************************* + * PARALLAX BACKGROUND + *********************************************/ + +.reveal.has-parallax-background .backgrounds { + transition: all 0.8s ease; +} + +/* Global transition speed settings */ +.reveal.has-parallax-background[data-transition-speed="fast"] .backgrounds { + transition-duration: 400ms; +} +.reveal.has-parallax-background[data-transition-speed="slow"] .backgrounds { + transition-duration: 1200ms; +} + + +/********************************************* + * OVERLAY FOR LINK PREVIEWS AND HELP + *********************************************/ + +.reveal > .overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 1000; + background: rgba( 0, 0, 0, 0.9 ); + opacity: 0; + visibility: hidden; + transition: all 0.3s ease; +} + .reveal > .overlay.visible { + opacity: 1; + visibility: visible; + } + + .reveal > .overlay .spinner { + position: absolute; + display: block; + top: 50%; + left: 50%; + width: 32px; + height: 32px; + margin: -16px 0 0 -16px; + z-index: 10; + background-image: url(data:image/gif;base64,R0lGODlhIAAgAPMAAJmZmf%2F%2F%2F6%2Bvr8nJybW1tcDAwOjo6Nvb26ioqKOjo7Ozs%2FLy8vz8%2FAAAAAAAAAAAACH%2FC05FVFNDQVBFMi4wAwEAAAAh%2FhpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh%2BQQJCgAAACwAAAAAIAAgAAAE5xDISWlhperN52JLhSSdRgwVo1ICQZRUsiwHpTJT4iowNS8vyW2icCF6k8HMMBkCEDskxTBDAZwuAkkqIfxIQyhBQBFvAQSDITM5VDW6XNE4KagNh6Bgwe60smQUB3d4Rz1ZBApnFASDd0hihh12BkE9kjAJVlycXIg7CQIFA6SlnJ87paqbSKiKoqusnbMdmDC2tXQlkUhziYtyWTxIfy6BE8WJt5YJvpJivxNaGmLHT0VnOgSYf0dZXS7APdpB309RnHOG5gDqXGLDaC457D1zZ%2FV%2FnmOM82XiHRLYKhKP1oZmADdEAAAh%2BQQJCgAAACwAAAAAIAAgAAAE6hDISWlZpOrNp1lGNRSdRpDUolIGw5RUYhhHukqFu8DsrEyqnWThGvAmhVlteBvojpTDDBUEIFwMFBRAmBkSgOrBFZogCASwBDEY%2FCZSg7GSE0gSCjQBMVG023xWBhklAnoEdhQEfyNqMIcKjhRsjEdnezB%2BA4k8gTwJhFuiW4dokXiloUepBAp5qaKpp6%2BHo7aWW54wl7obvEe0kRuoplCGepwSx2jJvqHEmGt6whJpGpfJCHmOoNHKaHx61WiSR92E4lbFoq%2BB6QDtuetcaBPnW6%2BO7wDHpIiK9SaVK5GgV543tzjgGcghAgAh%2BQQJCgAAACwAAAAAIAAgAAAE7hDISSkxpOrN5zFHNWRdhSiVoVLHspRUMoyUakyEe8PTPCATW9A14E0UvuAKMNAZKYUZCiBMuBakSQKG8G2FzUWox2AUtAQFcBKlVQoLgQReZhQlCIJesQXI5B0CBnUMOxMCenoCfTCEWBsJColTMANldx15BGs8B5wlCZ9Po6OJkwmRpnqkqnuSrayqfKmqpLajoiW5HJq7FL1Gr2mMMcKUMIiJgIemy7xZtJsTmsM4xHiKv5KMCXqfyUCJEonXPN2rAOIAmsfB3uPoAK%2B%2BG%2Bw48edZPK%2BM6hLJpQg484enXIdQFSS1u6UhksENEQAAIfkECQoAAAAsAAAAACAAIAAABOcQyEmpGKLqzWcZRVUQnZYg1aBSh2GUVEIQ2aQOE%2BG%2BcD4ntpWkZQj1JIiZIogDFFyHI0UxQwFugMSOFIPJftfVAEoZLBbcLEFhlQiqGp1Vd140AUklUN3eCA51C1EWMzMCezCBBmkxVIVHBWd3HHl9JQOIJSdSnJ0TDKChCwUJjoWMPaGqDKannasMo6WnM562R5YluZRwur0wpgqZE7NKUm%2BFNRPIhjBJxKZteWuIBMN4zRMIVIhffcgojwCF117i4nlLnY5ztRLsnOk%2BaV%2BoJY7V7m76PdkS4trKcdg0Zc0tTcKkRAAAIfkECQoAAAAsAAAAACAAIAAABO4QyEkpKqjqzScpRaVkXZWQEximw1BSCUEIlDohrft6cpKCk5xid5MNJTaAIkekKGQkWyKHkvhKsR7ARmitkAYDYRIbUQRQjWBwJRzChi9CRlBcY1UN4g0%2FVNB0AlcvcAYHRyZPdEQFYV8ccwR5HWxEJ02YmRMLnJ1xCYp0Y5idpQuhopmmC2KgojKasUQDk5BNAwwMOh2RtRq5uQuPZKGIJQIGwAwGf6I0JXMpC8C7kXWDBINFMxS4DKMAWVWAGYsAdNqW5uaRxkSKJOZKaU3tPOBZ4DuK2LATgJhkPJMgTwKCdFjyPHEnKxFCDhEAACH5BAkKAAAALAAAAAAgACAAAATzEMhJaVKp6s2nIkolIJ2WkBShpkVRWqqQrhLSEu9MZJKK9y1ZrqYK9WiClmvoUaF8gIQSNeF1Er4MNFn4SRSDARWroAIETg1iVwuHjYB1kYc1mwruwXKC9gmsJXliGxc%2BXiUCby9ydh1sOSdMkpMTBpaXBzsfhoc5l58Gm5yToAaZhaOUqjkDgCWNHAULCwOLaTmzswadEqggQwgHuQsHIoZCHQMMQgQGubVEcxOPFAcMDAYUA85eWARmfSRQCdcMe0zeP1AAygwLlJtPNAAL19DARdPzBOWSm1brJBi45soRAWQAAkrQIykShQ9wVhHCwCQCACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiRMDjI0Fd30%2FiI2UA5GSS5UDj2l6NoqgOgN4gksEBgYFf0FDqKgHnyZ9OX8HrgYHdHpcHQULXAS2qKpENRg7eAMLC7kTBaixUYFkKAzWAAnLC7FLVxLWDBLKCwaKTULgEwbLA4hJtOkSBNqITT3xEgfLpBtzE%2FjiuL04RGEBgwWhShRgQExHBAAh%2BQQJCgAAACwAAAAAIAAgAAAE7xDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfZiCqGk5dTESJeaOAlClzsJsqwiJwiqnFrb2nS9kmIcgEsjQydLiIlHehhpejaIjzh9eomSjZR%2BipslWIRLAgMDOR2DOqKogTB9pCUJBagDBXR6XB0EBkIIsaRsGGMMAxoDBgYHTKJiUYEGDAzHC9EACcUGkIgFzgwZ0QsSBcXHiQvOwgDdEwfFs0sDzt4S6BK4xYjkDOzn0unFeBzOBijIm1Dgmg5YFQwsCMjp1oJ8LyIAACH5BAkKAAAALAAAAAAgACAAAATwEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GGl6NoiPOH16iZKNlH6KmyWFOggHhEEvAwwMA0N9GBsEC6amhnVcEwavDAazGwIDaH1ipaYLBUTCGgQDA8NdHz0FpqgTBwsLqAbWAAnIA4FWKdMLGdYGEgraigbT0OITBcg5QwPT4xLrROZL6AuQAPUS7bxLpoWidY0JtxLHKhwwMJBTHgPKdEQAACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GAULDJCRiXo1CpGXDJOUjY%2BYip9DhToJA4RBLwMLCwVDfRgbBAaqqoZ1XBMHswsHtxtFaH1iqaoGNgAIxRpbFAgfPQSqpbgGBqUD1wBXeCYp1AYZ19JJOYgH1KwA4UBvQwXUBxPqVD9L3sbp2BNk2xvvFPJd%2BMFCN6HAAIKgNggY0KtEBAAh%2BQQJCgAAACwAAAAAIAAgAAAE6BDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfYIDMaAFdTESJeaEDAIMxYFqrOUaNW4E4ObYcCXaiBVEgULe0NJaxxtYksjh2NLkZISgDgJhHthkpU4mW6blRiYmZOlh4JWkDqILwUGBnE6TYEbCgevr0N1gH4At7gHiRpFaLNrrq8HNgAJA70AWxQIH1%2BvsYMDAzZQPC9VCNkDWUhGkuE5PxJNwiUK4UfLzOlD4WvzAHaoG9nxPi5d%2BjYUqfAhhykOFwJWiAAAIfkECQoAAAAsAAAAACAAIAAABPAQyElpUqnqzaciSoVkXVUMFaFSwlpOCcMYlErAavhOMnNLNo8KsZsMZItJEIDIFSkLGQoQTNhIsFehRww2CQLKF0tYGKYSg%2BygsZIuNqJksKgbfgIGepNo2cIUB3V1B3IvNiBYNQaDSTtfhhx0CwVPI0UJe0%2Bbm4g5VgcGoqOcnjmjqDSdnhgEoamcsZuXO1aWQy8KAwOAuTYYGwi7w5h%2BKr0SJ8MFihpNbx%2B4Erq7BYBuzsdiH1jCAzoSfl0rVirNbRXlBBlLX%2BBP0XJLAPGzTkAuAOqb0WT5AH7OcdCm5B8TgRwSRKIHQtaLCwg1RAAAOwAAAAAAAAAAAA%3D%3D); + + visibility: visible; + opacity: 0.6; + transition: all 0.3s ease; + } + + .reveal > .overlay header { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 40px; + z-index: 2; + border-bottom: 1px solid #222; + } + .reveal > .overlay header a { + display: inline-block; + width: 40px; + height: 40px; + line-height: 36px; + padding: 0 10px; + float: right; + opacity: 0.6; + + box-sizing: border-box; + } + .reveal > .overlay header a:hover { + opacity: 1; + } + .reveal > .overlay header a .icon { + display: inline-block; + width: 20px; + height: 20px; + + background-position: 50% 50%; + background-size: 100%; + background-repeat: no-repeat; + } + .reveal > .overlay header a.close .icon { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABkklEQVRYR8WX4VHDMAxG6wnoJrABZQPYBCaBTWAD2g1gE5gg6OOsXuxIlr40d81dfrSJ9V4c2VLK7spHuTJ/5wpM07QXuXc5X0opX2tEJcadjHuV80li/FgxTIEK/5QBCICBD6xEhSMGHgQPgBgLiYVAB1dpSqKDawxTohFw4JSEA3clzgIBPCURwE2JucBR7rhPJJv5OpJwDX+SfDjgx1wACQeJG1aChP9K/IMmdZ8DtESV1WyP3Bt4MwM6sj4NMxMYiqUWHQu4KYA/SYkIjOsm3BXYWMKFDwU2khjCQ4ELJUJ4SmClRArOCmSXGuKma0fYD5CbzHxFpCSGAhfAVSSUGDUk2BWZaff2g6GE15BsBQ9nwmpIGDiyHQddwNTMKkbZaf9fajXQca1EX44puJZUsnY0ObGmITE3GVLCbEhQUjGVt146j6oasWN+49Vph2w1pZ5EansNZqKBm1txbU57iRRcZ86RWMDdWtBJUHBHwoQPi1GV+JCbntmvok7iTX4/Up9mgyTc/FJYDTcndgH/AA5A/CHsyEkVAAAAAElFTkSuQmCC); + } + .reveal > .overlay header a.external .icon { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAcElEQVRYR+2WSQoAIQwEzf8f7XiOMkUQxUPlGkM3hVmiQfQR9GYnH1SsAQlI4DiBqkCMoNb9y2e90IAEJPAcgdznU9+engMaeJ7Azh5Y1U67gAho4DqBqmB1buAf0MB1AlVBek83ZPkmJMGc1wAR+AAqod/B97TRpQAAAABJRU5ErkJggg==); + } + + .reveal > .overlay .viewport { + position: absolute; + display: flex; + top: 40px; + right: 0; + bottom: 0; + left: 0; + } + + .reveal > .overlay.overlay-preview .viewport iframe { + width: 100%; + height: 100%; + max-width: 100%; + max-height: 100%; + border: 0; + + opacity: 0; + visibility: hidden; + transition: all 0.3s ease; + } + + .reveal > .overlay.overlay-preview.loaded .viewport iframe { + opacity: 1; + visibility: visible; + } + + .reveal > .overlay.overlay-preview.loaded .viewport-inner { + position: absolute; + z-index: -1; + left: 0; + top: 45%; + width: 100%; + text-align: center; + letter-spacing: normal; + } + .reveal > .overlay.overlay-preview .x-frame-error { + opacity: 0; + transition: opacity 0.3s ease 0.3s; + } + .reveal > .overlay.overlay-preview.loaded .x-frame-error { + opacity: 1; + } + + .reveal > .overlay.overlay-preview.loaded .spinner { + opacity: 0; + visibility: hidden; + transform: scale(0.2); + } + + .reveal > .overlay.overlay-help .viewport { + overflow: auto; + color: #fff; + } + + .reveal > .overlay.overlay-help .viewport .viewport-inner { + width: 600px; + margin: auto; + padding: 20px 20px 80px 20px; + text-align: center; + letter-spacing: normal; + } + + .reveal > .overlay.overlay-help .viewport .viewport-inner .title { + font-size: 20px; + } + + .reveal > .overlay.overlay-help .viewport .viewport-inner table { + border: 1px solid #fff; + border-collapse: collapse; + font-size: 16px; + } + + .reveal > .overlay.overlay-help .viewport .viewport-inner table th, + .reveal > .overlay.overlay-help .viewport .viewport-inner table td { + width: 200px; + padding: 14px; + border: 1px solid #fff; + vertical-align: middle; + } + + .reveal > .overlay.overlay-help .viewport .viewport-inner table th { + padding-top: 20px; + padding-bottom: 20px; + } + + +/********************************************* + * PLAYBACK COMPONENT + *********************************************/ + +.reveal .playback { + position: absolute; + left: 15px; + bottom: 20px; + z-index: 30; + cursor: pointer; + transition: all 400ms ease; + -webkit-tap-highlight-color: rgba( 0, 0, 0, 0 ); +} + +.reveal.overview .playback { + opacity: 0; + visibility: hidden; +} + + +/********************************************* + * CODE HIGHLGIHTING + *********************************************/ + +.reveal .hljs table { + margin: initial; +} + +.reveal .hljs-ln-code, +.reveal .hljs-ln-numbers { + padding: 0; + border: 0; +} + +.reveal .hljs-ln-numbers { + opacity: 0.6; + padding-right: 0.75em; + text-align: right; + vertical-align: top; +} + +.reveal .hljs[data-line-numbers]:not([data-line-numbers=""]) tr:not(.highlight-line) { + opacity: 0.4; +} + + +/********************************************* + * ROLLING LINKS + *********************************************/ + +.reveal .roll { + display: inline-block; + line-height: 1.2; + overflow: hidden; + + vertical-align: top; + perspective: 400px; + perspective-origin: 50% 50%; +} + .reveal .roll:hover { + background: none; + text-shadow: none; + } +.reveal .roll span { + display: block; + position: relative; + padding: 0 2px; + + pointer-events: none; + transition: all 400ms ease; + transform-origin: 50% 0%; + transform-style: preserve-3d; + backface-visibility: hidden; +} + .reveal .roll:hover span { + background: rgba(0,0,0,0.5); + transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg ); + } +.reveal .roll span:after { + content: attr(data-title); + + display: block; + position: absolute; + left: 0; + top: 0; + padding: 0 2px; + backface-visibility: hidden; + transform-origin: 50% 0%; + transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg ); +} + + +/********************************************* + * SPEAKER NOTES + *********************************************/ + +$notesWidthPercent: 25%; + +// Hide on-page notes +.reveal aside.notes { + display: none; +} + +// An interface element that can optionally be used to show the +// speaker notes to all viewers, on top of the presentation +.reveal .speaker-notes { + display: none; + position: absolute; + width: $notesWidthPercent / (1-$notesWidthPercent/100) * 1%; + height: 100%; + top: 0; + left: 100%; + padding: 14px 18px 14px 18px; + z-index: 1; + font-size: 18px; + line-height: 1.4; + border: 1px solid rgba( 0, 0, 0, 0.05 ); + color: #222; + background-color: #f5f5f5; + overflow: auto; + box-sizing: border-box; + text-align: left; + font-family: Helvetica, sans-serif; + -webkit-overflow-scrolling: touch; + + .notes-placeholder { + color: #ccc; + font-style: italic; + } + + &:focus { + outline: none; + } + + &:before { + content: 'Speaker notes'; + display: block; + margin-bottom: 10px; + opacity: 0.5; + } +} + + +.reveal.show-notes { + max-width: 100% - $notesWidthPercent; + overflow: visible; +} + +.reveal.show-notes .speaker-notes { + display: block; +} + +@media screen and (min-width: 1600px) { + .reveal .speaker-notes { + font-size: 20px; + } +} + +@media screen and (max-width: 1024px) { + .reveal.show-notes { + border-left: 0; + max-width: none; + max-height: 70%; + max-height: 70vh; + overflow: visible; + } + + .reveal.show-notes .speaker-notes { + top: 100%; + left: 0; + width: 100%; + height: (30/0.7)*1%; + height: 30vh; + border: 0; + } +} + +@media screen and (max-width: 600px) { + .reveal.show-notes { + max-height: 60%; + max-height: 60vh; + } + + .reveal.show-notes .speaker-notes { + top: 100%; + height: (40/0.6)*1%; + height: 40vh; + } + + .reveal .speaker-notes { + font-size: 14px; + } +} + + +/********************************************* + * ZOOM PLUGIN + *********************************************/ + +.zoomed .reveal *, +.zoomed .reveal *:before, +.zoomed .reveal *:after { + backface-visibility: visible !important; +} + +.zoomed .reveal .progress, +.zoomed .reveal .controls { + opacity: 0; +} + +.zoomed .reveal .roll span { + background: none; +} + +.zoomed .reveal .roll span:after { + visibility: hidden; +} diff --git a/talks/css/theme/README.md b/talks/css/theme/README.md new file mode 100755 index 000000000..8ae164bbc --- /dev/null +++ b/talks/css/theme/README.md @@ -0,0 +1,21 @@ +## Dependencies + +Themes are written using Sass to keep things modular and reduce the need for repeated selectors across files. Make sure that you have the reveal.js development environment including the Grunt dependencies installed before proceeding: https://github.com/hakimel/reveal.js#full-setup + +## Creating a Theme + +To create your own theme, start by duplicating a ```.scss``` file in [/css/theme/source](https://github.com/hakimel/reveal.js/blob/master/css/theme/source). It will be automatically compiled by Grunt from Sass to CSS (see the [Gruntfile](https://github.com/hakimel/reveal.js/blob/master/Gruntfile.js)) when you run `npm run build -- css-themes`. + +Each theme file does four things in the following order: + +1. **Include [/css/theme/template/mixins.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/mixins.scss)** +Shared utility functions. + +2. **Include [/css/theme/template/settings.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/settings.scss)** +Declares a set of custom variables that the template file (step 4) expects. Can be overridden in step 3. + +3. **Override** +This is where you override the default theme. Either by specifying variables (see [settings.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/settings.scss) for reference) or by adding any selectors and styles you please. + +4. **Include [/css/theme/template/theme.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/theme.scss)** +The template theme file which will generate final CSS output based on the currently defined variables. diff --git a/talks/css/theme/beige.css b/talks/css/theme/beige.css new file mode 100755 index 000000000..615dd6d1d --- /dev/null +++ b/talks/css/theme/beige.css @@ -0,0 +1,277 @@ +/** + * Beige theme for reveal.js. + * + * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se + */ +@import url(../../lib/font/league-gothic/league-gothic.css); +@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #f7f2d3; + background: -moz-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%); + background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, white), color-stop(100%, #f7f2d3)); + background: -webkit-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%); + background: -o-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%); + background: -ms-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%); + background: radial-gradient(center, circle cover, white 0%, #f7f2d3 100%); + background-color: #f7f3de; } + +.reveal { + font-family: "Lato", sans-serif; + font-size: 40px; + font-weight: normal; + color: #333; } + +::selection { + color: #fff; + background: rgba(79, 64, 28, 0.99); + text-shadow: none; } + +::-moz-selection { + color: #fff; + background: rgba(79, 64, 28, 0.99); + text-shadow: none; } + +.reveal .slides section, +.reveal .slides section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #333; + font-family: "League Gothic", Impact, sans-serif; + font-weight: normal; + line-height: 1.2; + letter-spacing: normal; + text-transform: uppercase; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 3.77em; } + +.reveal h2 { + font-size: 2.11em; } + +.reveal h3 { + font-size: 1.55em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15); } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); } + +.reveal code { + font-family: monospace; + text-transform: none; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tbody tr:last-child th, +.reveal table tbody tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; + font-size: smaller; } + +.reveal sub { + vertical-align: sub; + font-size: smaller; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #8b743d; + text-decoration: none; + -webkit-transition: color .15s ease; + -moz-transition: color .15s ease; + transition: color .15s ease; } + +.reveal a:hover { + color: #c0a86e; + text-shadow: none; + border: none; } + +.reveal .roll span:after { + color: #fff; + background: #564826; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #333; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all .15s linear; + -moz-transition: all .15s linear; + transition: all .15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #8b743d; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls { + color: #8b743d; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); + color: #8b743d; } + +.reveal .progress span { + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +/********************************************* + * PRINT BACKGROUND + *********************************************/ +@media print { + .backgrounds { + background-color: #f7f3de; } } diff --git a/talks/css/theme/black.css b/talks/css/theme/black.css new file mode 100755 index 000000000..7dd88c2c7 --- /dev/null +++ b/talks/css/theme/black.css @@ -0,0 +1,273 @@ +/** + * Black theme for reveal.js. This is the opposite of the 'white' theme. + * + * By Hakim El Hattab, http://hakim.se + */ +@import url(../../lib/font/source-sans-pro/source-sans-pro.css); +section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 { + color: #222; } + +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #191919; + background-color: #191919; } + +.reveal { + font-family: "Source Sans Pro", Helvetica, sans-serif; + font-size: 42px; + font-weight: normal; + color: #fff; } + +::selection { + color: #fff; + background: #bee4fd; + text-shadow: none; } + +::-moz-selection { + color: #fff; + background: #bee4fd; + text-shadow: none; } + +.reveal .slides section, +.reveal .slides section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #fff; + font-family: "Source Sans Pro", Helvetica, sans-serif; + font-weight: 600; + line-height: 1.2; + letter-spacing: normal; + text-transform: uppercase; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 2.5em; } + +.reveal h2 { + font-size: 1.6em; } + +.reveal h3 { + font-size: 1.3em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: none; } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); } + +.reveal code { + font-family: monospace; + text-transform: none; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tbody tr:last-child th, +.reveal table tbody tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; + font-size: smaller; } + +.reveal sub { + vertical-align: sub; + font-size: smaller; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #42affa; + text-decoration: none; + -webkit-transition: color .15s ease; + -moz-transition: color .15s ease; + transition: color .15s ease; } + +.reveal a:hover { + color: #8dcffc; + text-shadow: none; + border: none; } + +.reveal .roll span:after { + color: #fff; + background: #068de9; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #fff; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all .15s linear; + -moz-transition: all .15s linear; + transition: all .15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #42affa; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls { + color: #42affa; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); + color: #42affa; } + +.reveal .progress span { + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +/********************************************* + * PRINT BACKGROUND + *********************************************/ +@media print { + .backgrounds { + background-color: #191919; } } diff --git a/talks/css/theme/blood.css b/talks/css/theme/blood.css new file mode 100755 index 000000000..5cbd488b7 --- /dev/null +++ b/talks/css/theme/blood.css @@ -0,0 +1,296 @@ +/** + * Blood theme for reveal.js + * Author: Walther http://github.com/Walther + * + * Designed to be used with highlight.js theme + * "monokai_sublime.css" available from + * https://github.com/isagalaev/highlight.js/ + * + * For other themes, change $codeBackground accordingly. + * + */ +@import url(https://fonts.googleapis.com/css?family=Ubuntu:300,700,300italic,700italic); +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #222; + background-color: #222; } + +.reveal { + font-family: Ubuntu, "sans-serif"; + font-size: 40px; + font-weight: normal; + color: #eee; } + +::selection { + color: #fff; + background: #a23; + text-shadow: none; } + +::-moz-selection { + color: #fff; + background: #a23; + text-shadow: none; } + +.reveal .slides section, +.reveal .slides section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #eee; + font-family: Ubuntu, "sans-serif"; + font-weight: normal; + line-height: 1.2; + letter-spacing: normal; + text-transform: uppercase; + text-shadow: 2px 2px 2px #222; + word-wrap: break-word; } + +.reveal h1 { + font-size: 3.77em; } + +.reveal h2 { + font-size: 2.11em; } + +.reveal h3 { + font-size: 1.55em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15); } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); } + +.reveal code { + font-family: monospace; + text-transform: none; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tbody tr:last-child th, +.reveal table tbody tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; + font-size: smaller; } + +.reveal sub { + vertical-align: sub; + font-size: smaller; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #a23; + text-decoration: none; + -webkit-transition: color .15s ease; + -moz-transition: color .15s ease; + transition: color .15s ease; } + +.reveal a:hover { + color: #dd5566; + text-shadow: none; + border: none; } + +.reveal .roll span:after { + color: #fff; + background: #6a1520; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #eee; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all .15s linear; + -moz-transition: all .15s linear; + transition: all .15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #a23; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls { + color: #a23; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); + color: #a23; } + +.reveal .progress span { + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +/********************************************* + * PRINT BACKGROUND + *********************************************/ +@media print { + .backgrounds { + background-color: #222; } } + +.reveal p { + font-weight: 300; + text-shadow: 1px 1px #222; } + +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + font-weight: 700; } + +.reveal p code { + background-color: #23241f; + display: inline-block; + border-radius: 7px; } + +.reveal small code { + vertical-align: baseline; } diff --git a/talks/css/theme/bsu.css b/talks/css/theme/bsu.css new file mode 100644 index 000000000..ca7ffc16e --- /dev/null +++ b/talks/css/theme/bsu.css @@ -0,0 +1,547 @@ +/** + * White theme for reveal.js. This is the opposite of the 'black' theme. + * + * By Hakim El Hattab, http://hakim.se + */ +@import url(../../lib/font/source-sans-pro/source-sans-pro.css); +section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 { + color: #f9fafb; } + +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #f9fafb; + background-color: #f9fafb; } + +.reveal { + font-family: "Source Sans Pro", Helvetica, sans-serif; + font-size: 38px; + font-weight: normal; + color: #3F4444; } + +::selection { + color: #f9fafb; + background: #0033a0; + text-shadow: none; } + +::-moz-selection { + color: #f9fafb; + background: #0033a0; + text-shadow: none; } + +.reveal .slides section, +.reveal .slides section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #3033a0; + font-family: "Lato", Helvetica, sans-serif; + font-weight: 600; + line-height: 1.2; + letter-spacing: normal; + text-transform: none; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 2.5em; } + +.reveal h2 { + font-size: 1.6em; } + +.reveal h3 { + font-size: 1.3em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: none; } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } + +.reveal code { + font-family: monospace; + text-transform: none; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tbody tr:last-child th, +.reveal table tbody tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; + font-size: smaller; } + +.reveal sub { + vertical-align: sub; + font-size: smaller; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #0033a0; + text-decoration: underline #0033a0 solid; + -webkit-text-decoration: underline #0033a0 solid; + -moz-text-decoration: underline #0033a0 solid; + -webkit-transition: color .15s ease; + -moz-transition: color .15s ease; + transition: color .15s ease; } + +.reveal a:hover { + color: #0072ce; + text-shadow: none; + border: none; + text-decoration: underline #0033a0 solid; + -webkit-text-decoration: underline #0033a0 solid; + -moz-text-decoration: underline #0033a0 solid; + -webkit-transition: color 0.15s ease; + -moz-transition: color 0.15s ease; + transition: color 0.15s ease;} + +.reveal .roll span:after { + color: #f9fafb; + background: #006ba6; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #3F4444; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all .15s linear; + -moz-transition: all .15s linear; + transition: all .15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #0033a0; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls { + color: #D64309; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); + color: #D64309; + height: .5rem; } + +.reveal .progress span { + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +.reveal footer { + position: fixed; + height: 26px; + width: 100%; + bottom: 15px; + left: 0; + z-index: 10; + font-size: 35%; + text-align:left; + background-repeat: no-repeat; + background-size: auto 74%; + background-position: 7px 0; + font-family: "Source Sans Pro", Helvetica, sans-serif; +} +.reveal footer .copyright { + margin:5px; + display: flex; + flex-direction: row; + justify-content: start; + align-items: center; +} +.reveal footer .copyright * { + vertical-align: middle; +} + +.reveal footer .copyright p { + margin: .3em .3em; +} +.reveal footer span {color: #3F4444;} + +section *, +body .reveal .slides section .fragment { + transition-delay: 0s; + -webkit-transition-delay: 0s; + transition: all 0.4s ease; + -webkit-transition: all 0.4s ease; +} + +section .row:before, +section .row:after { + content: ""; + display: table; + clear: both; +} + +section .row { + margin: 0.15em 0em; +} + +section .row *[class*='col-'] { + box-sizing: border-box; + position: relative; + left: 0; + float: left; + min-height: 1px; + padding: 0em 0.15em; +} + +/*for tables*/ +td { + font-size: 0.6em !important; + text-align: center !important; +} +th { + font-size: 0.7em !important; + text-align: center !important; +} + +.row-flex { + display: flex; + justify-content: stretch; +} + +.table-vert td, +.table-vert th { + border-right: solid 1px #d2d2d2; + border-left: solid 1px #d2d2d2; +} + +.table-leftalign td { + font-size: 0.6em !important; + text-align: left !important; +} +.table-leftalign th { + font-size: 0.6em !important; + text-align: left !important; +} + +.no-top td, +.no-top th { + border-top:0 none !important; +} +.no-bottom td, +.no-bottom th { + border-bottom:0 none !important; +} + +.vert-align { + display: flex; + flex-direction: column; + justify-content: center; +} + +.col-05 { width: 0.5%; } +.col-1 { width: 1%; } +.col-2 { width: 2%; } +.col-3 { width: 3%; } +.col-4 { width: 4%; } +.col-5 { width: 5%; } +.col-6 { width: 6%; } +.col-7 { width: 7%; } +.col-8 { width: 8%; } +.col-9 { width: 9%; } +.col-10 { width: 10%; } +.col-11 { width: 11%; } +.col-12 { width: 12%; } +.col-13 { width: 13%; } +.col-14 { width: 14%; } +.col-15 { width: 15%; } +.col-16 { width: 16%; } +.col-17 { width: 17%; } +.col-18 { width: 18%; } +.col-19 { width: 19%; } +.col-20 { width: 20%; } +.col-21 { width: 21%; } +.col-22 { width: 22%; } +.col-23 { width: 23%; } +.col-24 { width: 24%; } +.col-25 { width: 25%; } +.col-26 { width: 26%; } +.col-27 { width: 27%; } +.col-28 { width: 28%; } +.col-29 { width: 29%; } +.col-30 { width: 30%; } +.col-31 { width: 31%; } +.col-32 { width: 32%; } +.col-33 { width: 33.33%; } +.col-34 { width: 34%; } +.col-35 { width: 35%; } +.col-36 { width: 36%; } +.col-37 { width: 37%; } +.col-38 { width: 38%; } +.col-39 { width: 39%; } +.col-40 { width: 40%; } +.col-41 { width: 41%; } +.col-42 { width: 42%; } +.col-43 { width: 43%; } +.col-44 { width: 44%; } +.col-45 { width: 45%; } +.col-46 { width: 46%; } +.col-47 { width: 47%; } +.col-48 { width: 48%; } +.col-49 { width: 49%; } +.col-50 { width: 50%; } +.col-51 { width: 51%; } +.col-52 { width: 52%; } +.col-53 { width: 53%; } +.col-54 { width: 54%; } +.col-55 { width: 55%; } +.col-56 { width: 56%; } +.col-57 { width: 57%; } +.col-58 { width: 58%; } +.col-59 { width: 59%; } +.col-60 { width: 60%; } +.col-61 { width: 61%; } +.col-62 { width: 62%; } +.col-63 { width: 63%; } +.col-64 { width: 64%; } +.col-65 { width: 65%; } +.col-66 { width: 66.66%; } +.col-67 { width: 67%; } +.col-68 { width: 68%; } +.col-69 { width: 69%; } +.col-70 { width: 70%; } +.col-71 { width: 71%; } +.col-72 { width: 72%; } +.col-73 { width: 73%; } +.col-74 { width: 74%; } +.col-75 { width: 75%; } +.col-76 { width: 76%; } +.col-77 { width: 77%; } +.col-78 { width: 78%; } +.col-79 { width: 79%; } +.col-80 { width: 80%; } +.col-81 { width: 81%; } +.col-82 { width: 82%; } +.col-83 { width: 83%; } +.col-84 { width: 84%; } +.col-85 { width: 85%; } +.col-86 { width: 86%; } +.col-87 { width: 87%; } +.col-88 { width: 88%; } +.col-89 { width: 89%; } +.col-90 { width: 90%; } +.col-91 { width: 91%; } +.col-92 { width: 92%; } +.col-93 { width: 93%; } +.col-94 { width: 94%; } +.col-95 { width: 95%; } +.col-96 { width: 96%; } +.col-97 { width: 97%; } +.col-98 { width: 98%; } +.col-99 { width: 99%; } +.col-100 { width: 100%; } + +.push-5 { left: 5% !important; } +.push-10 { left: 10% !important; } +.push-15 { left: 15% !important; } +.push-20 { left: 20% !important; } +.push-25 { left: 25% !important; } +.push-30 { left: 30% !important; } +.push-33 { left: 33.33% !important; } +.push-35 { left: 35% !important; } +.push-40 { left: 40% !important; } +.push-45 { left: 45% !important; } +.push-50 { left: 50% !important; } +.push-60 { left: 60% !important; } +.push-66 { left: 66.66% !important; } +.push-70 { left: 70% !important; } +.push-75 { left: 75% !important; } +.push-80 { left: 80% !important; } +.push-90 { left: 90% !important; } +.push-100 { left: 100% !important; } + +.pull-5 { left: -5% !important; } +.pull-10 { left: -10% !important; } +.pull-15 { left: -15% !important; } +.pull-20 { left: -20% !important; } +.pull-25 { left: -25% !important; } +.pull-30 { left: -30% !important; } +.pull-35 { left: -35% !important; } +.pull-33 { left: -33.33% !important; } +.pull-40 { left: -40% !important; } +.pull-45 { left: -45% !important; } +.pull-50 { left: -50% !important; } +.pull-60 { left: -60% !important; } +.pull-66 { left: -66.66% !important; } +.pull-70 { left: -70% !important; } +.pull-75 { left: -75% !important; } +.pull-80 { left: -80% !important; } +.pull-90 { left: -90% !important; } +.pull-100 { left: -100% !important; } + + +.reveal .content-box { + display: flex !important; + flex-direction: column !important; + align-items: center !important; + padding: 1.5em 2em 1em; + background: #000000; + opacity: 0.75;} + +.reveal .content-box h1 { + color: #3399ff; +} + + +.no-margin-top { + margin-top: 0 !important; +} +.no-margin-bottom { + margin-bottom: 0 !important; +} + + +/********************************************* + * PRINT BACKGROUND + *********************************************/ +@media print { + .backgrounds { + background-color: #f9fafb; } } diff --git a/talks/css/theme/cwi-dark-logo.css b/talks/css/theme/cwi-dark-logo.css new file mode 100644 index 000000000..3b0b5fa78 --- /dev/null +++ b/talks/css/theme/cwi-dark-logo.css @@ -0,0 +1,319 @@ +/** + * cwi-dark-logo theme with CWI colors and library logo for reveal.js. Ryan Randall made this based off Hakim El Hattab's "black" theme. + * + * Copyright (C) 2019 Ryan Randall, http://www.ryanpatrickrandall.com + * Licensed CC-BY-SA (Attribution, Share-alike) + */ +@import url(../../lib/font/source-sans-pro/source-sans-pro.css); +section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 { + color: #222; } + +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #4a4a4a; + background-color: #4a4a4a; } + +.reveal { + font-family: "Source Sans Pro", Helvetica, sans-serif; + font-size: 38px; + font-weight: normal; + color: #ededed; } + +::selection { + color: #780000; + background: #cccccc; + text-shadow: none; } + +.reveal .slides > section, +.reveal .slides > section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #eeb111; + font-family: "Lato", , Helvetica, sans-serif; + font-weight: 600; + line-height: 1.2; + letter-spacing: normal; + text-transform: none; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 2.5em; } + +.reveal h2 { + font-size: 1.6em; } + +.reveal h3 { + font-size: 1.3em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: none; } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal q, +.reveal blockquote { + quotes: none; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } + +.reveal code { + font-family: monospace; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; } + +.reveal sub { + vertical-align: sub; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #cdcd9b; + text-decoration: underline #cdcd9b dotted; + -webkit-text-decoration: underline #cdcd9b dotted; + -moz-text-decoration: underline #cdcd9b dotted; + -webkit-transition: color 0.15s ease; + -moz-transition: color 0.15s ease; + transition: color 0.15s ease; } + +.reveal a:hover { + color: #eeb111; + text-shadow: none; + border: none; + text-decoration: underline #eeb111 dotted; + -webkit-text-decoration: underline #eeb111 dotted; + -moz-text-decoration: underline #eeb111 dotted; + -webkit-transition: color 0.15s ease; + -moz-transition: color 0.15s ease; + transition: color 0.15s ease; } + +.reveal .roll span:after { + color: #ededed; + background: #780000; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #cccccc; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all 0.15s linear; + -moz-transition: all 0.15s linear; + transition: all 0.15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #cccccc; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls .navigate-left, +.reveal .controls .navigate-left.enabled { + border-right-color: #780000; } + +.reveal .controls .navigate-right, +.reveal .controls .navigate-right.enabled { + border-left-color: #780000; } + +.reveal .controls .navigate-up, +.reveal .controls .navigate-up.enabled { + border-bottom-color: #780000; } + +.reveal .controls .navigate-down, +.reveal .controls .navigate-down.enabled { + border-top-color: #780000; } + +.reveal .controls .navigate-left.enabled:hover { + border-right-color: #2c0000; } + +.reveal .controls .navigate-right.enabled:hover { + border-left-color: #2c0000; } + +.reveal .controls .navigate-up.enabled:hover { + border-bottom-color: #2c0000; } + +.reveal .controls .navigate-down.enabled:hover { + border-top-color: #2c0000; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); + height: 9px;} + +.reveal .progress span { + background: #780000; + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + + .reveal footer{ + position: fixed; + height: 26px; + width: 100%; + bottom: 12px; + left: 0; + z-index: 10; + font-size: 35%; + text-align:left; + background-image: url(../../images/CWI-library-logo.jpg); + background-repeat: no-repeat; + background-size: auto 74%; + background-position: 7px 0; + font-family:; +} +.reveal footer .copyright{ + margin:5px 12px 0 70px; +} +.reveal footer .copyright a img{ + vertical-align: middle; +} +.reveal footer span {color: #cccccc;} \ No newline at end of file diff --git a/talks/css/theme/cwi-dark.css b/talks/css/theme/cwi-dark.css new file mode 100644 index 000000000..668b55041 --- /dev/null +++ b/talks/css/theme/cwi-dark.css @@ -0,0 +1,335 @@ +/** + * cwi-dark theme with CWI colors for reveal.js. Ryan Randall made this based off Hakim El Hattab's "black" theme. + * + * Copyright (C) 2017 Ryan Randall, http://www.ryanpatrickrandall.com + * Licensed CC-BY-SA (Attribution, Share-alike) + */ +@import url(../../lib/font/source-sans-pro/source-sans-pro.css); +section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 { + color: #222; } + +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #4a4a4a; + background-color: #4a4a4a; } + +.reveal { + font-family: "Source Sans Pro", Helvetica, sans-serif; + font-size: 38px; + font-weight: normal; + color: #ededed; } + +::selection { + color: #780000; + background: #cccccc; + text-shadow: none; } + +.reveal .slides > section, +.reveal .slides > section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #eeb111; + font-family: "Lato", , Helvetica, sans-serif; + font-weight: 600; + line-height: 1.2; + letter-spacing: normal; + text-transform: none; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 2.5em; } + +.reveal h2 { + font-size: 1.6em; } + +.reveal h3 { + font-size: 1.3em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: none; } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal q, +.reveal blockquote { + quotes: none; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } + +.reveal code { + font-family: monospace; + text-transform: none; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; + font-size: smaller; } + +.reveal sub { + vertical-align: sub; + font-size: smaller; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #cdcd9b; + text-decoration: underline #cdcd9b solid; + -webkit-text-decoration: underline #cdcd9b solid; + -moz-text-decoration: underline #cdcd9b solid; + -webkit-transition: color 0.15s ease; + -moz-transition: color 0.15s ease; + transition: color 0.15s ease; } + +.reveal a:hover { + color: #eeb111; + text-shadow: none; + border: none; + text-decoration: underline #eeb111 solid; + -webkit-text-decoration: underline #eeb111 solid; + -moz-text-decoration: underline #eeb111 solid; + -webkit-transition: color 0.15s ease; + -moz-transition: color 0.15s ease; + transition: color 0.15s ease; } + +.reveal .roll span:after { + color: #ededed; + background: #780000; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #cccccc; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all 0.15s linear; + -moz-transition: all 0.15s linear; + transition: all 0.15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #cccccc; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +/* commented out +.reveal .controls .navigate-left, +.reveal .controls .navigate-left.enabled { + border-right-color: #780000; } + +.reveal .controls .navigate-right, +.reveal .controls .navigate-right.enabled { + border-left-color: #780000; } + +.reveal .controls .navigate-up, +.reveal .controls .navigate-up.enabled { + border-bottom-color: #780000; } + +.reveal .controls .navigate-down, +.reveal .controls .navigate-down.enabled { + border-top-color: #780000; } + +.reveal .controls .navigate-left.enabled:hover { + border-right-color: #2c0000; } + +.reveal .controls .navigate-right.enabled:hover { + border-left-color: #2c0000; } + +.reveal .controls .navigate-up.enabled:hover { + border-bottom-color: #2c0000; } + +.reveal .controls .navigate-down.enabled:hover { + border-top-color: #2c0000; } + +*/ + +.reveal .controls button { + color: #eeb111; +} +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); + height: 9px;} + +.reveal .progress span { + background: #780000; + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +.reveal footer { + position: fixed; + height: 26px; + width: 100%; + bottom: 15px; + left: 0; + z-index: 10; + font-size: 35%; + text-align:left; + background-repeat: no-repeat; + background-size: auto 74%; + background-position: 7px 0; + font-family: "Source Sans Pro", Helvetica, sans-serif; +} +.reveal footer .copyright { + margin:5px; + display: flex; + flex-direction: row; + justify-content: start; + align-items: center; +} +.reveal footer .copyright * { + vertical-align: middle; +} + +.reveal footer .copyright p { + margin: .3em .3em; +} +.reveal footer span {color: #cccccc;} \ No newline at end of file diff --git a/talks/css/theme/cwi-river-logo.css b/talks/css/theme/cwi-river-logo.css new file mode 100644 index 000000000..19b04afc3 --- /dev/null +++ b/talks/css/theme/cwi-river-logo.css @@ -0,0 +1,319 @@ +/** + * cwi-river-logo theme with CWI colors and library logo for reveal.js. Ryan Randall made this based off Hakim El Hattab's "black" theme. + * + * Copyright (C) 2019 Ryan Randall, http://www.ryanpatrickrandall.com + * Licensed CC-BY-SA (Attribution, Share-alike) + */ +@import url(../../lib/font/source-sans-pro/source-sans-pro.css); +section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 { + color: #222; } + +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #4a4a4a; + background-color: #4a4a4a; } + +.reveal { + font-family: "Source Sans Pro", Helvetica, sans-serif; + font-size: 38px; + font-weight: normal; + color: #ededed; } + +::selection { + color: #780000; + background: #cccccc; + text-shadow: none; } + +.reveal .slides > section, +.reveal .slides > section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #eeb111; + font-family: "Lato", Helvetica, sans-serif; + font-weight: 600; + line-height: 1.2; + letter-spacing: normal; + text-transform: none; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 2.5em; } + +.reveal h2 { + font-size: 1.6em; } + +.reveal h3 { + font-size: 1.3em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: none; } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal q, +.reveal blockquote { + quotes: none; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } + +.reveal code { + font-family: monospace; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; } + +.reveal sub { + vertical-align: sub; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #cdcd9b; + text-decoration: underline #cdcd9b dotted; + -webkit-text-decoration: underline #cdcd9b dotted; + -moz-text-decoration: underline #cdcd9b dotted; + -webkit-transition: color 0.15s ease; + -moz-transition: color 0.15s ease; + transition: color 0.15s ease; } + +.reveal a:hover { + color: #eeb111; + text-shadow: none; + border: none; + text-decoration: underline #eeb111 dotted; + -webkit-text-decoration: underline #eeb111 dotted; + -moz-text-decoration: underline #eeb111 dotted; + -webkit-transition: color 0.15s ease; + -moz-transition: color 0.15s ease; + transition: color 0.15s ease; } + +.reveal .roll span:after { + color: #ededed; + background: #780000; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #cccccc; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all 0.15s linear; + -moz-transition: all 0.15s linear; + transition: all 0.15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #cccccc; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls .navigate-left, +.reveal .controls .navigate-left.enabled { + border-right-color: #780000; } + +.reveal .controls .navigate-right, +.reveal .controls .navigate-right.enabled { + border-left-color: #780000; } + +.reveal .controls .navigate-up, +.reveal .controls .navigate-up.enabled { + border-bottom-color: #780000; } + +.reveal .controls .navigate-down, +.reveal .controls .navigate-down.enabled { + border-top-color: #780000; } + +.reveal .controls .navigate-left.enabled:hover { + border-right-color: #2c0000; } + +.reveal .controls .navigate-right.enabled:hover { + border-left-color: #2c0000; } + +.reveal .controls .navigate-up.enabled:hover { + border-bottom-color: #2c0000; } + +.reveal .controls .navigate-down.enabled:hover { + border-top-color: #2c0000; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); + height: 9px;} + +.reveal .progress span { + background: #780000; + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + + .reveal footer{ + position: fixed; + height: 26px; + width: 100%; + bottom: 12px; + left: 0; + z-index: 10; + font-size: 35%; + text-align:left; + background-image: url(../../images/cwi-logo-small.jpg); + background-repeat: no-repeat; + background-size: auto 74%; + background-position: 7px 0; + font-family: "Source Sans Pro", Helvetica, sans-serif; +} +.reveal footer .copyright{ + margin:5px 12px 0 70px; +} +.reveal footer .copyright a img{ + vertical-align: middle; +} +.reveal footer span {color: #cccccc;} \ No newline at end of file diff --git a/talks/css/theme/cwi-river.css b/talks/css/theme/cwi-river.css new file mode 100644 index 000000000..8fad34dd1 --- /dev/null +++ b/talks/css/theme/cwi-river.css @@ -0,0 +1,547 @@ +/** + * White theme for reveal.js. This is the opposite of the 'black' theme. + * + * By Hakim El Hattab, http://hakim.se + */ +@import url(../../lib/font/source-sans-pro/source-sans-pro.css); +section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 { + color: #f9fafb; } + +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #f9fafb; + background-color: #f9fafb; } + +.reveal { + font-family: "Source Sans Pro", Helvetica, sans-serif; + font-size: 38px; + font-weight: normal; + color: #111111; } + +::selection { + color: #f9fafb; + background: #004F59; + text-shadow: none; } + +::-moz-selection { + color: #f9fafb; + background: #004F59; + text-shadow: none; } + +.reveal .slides section, +.reveal .slides section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #004F59; + font-family: "Lato", Helvetica, sans-serif; + font-weight: 600; + line-height: 1.2; + letter-spacing: normal; + text-transform: none; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 2.5em; } + +.reveal h2 { + font-size: 1.6em; } + +.reveal h3 { + font-size: 1.3em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: none; } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } + +.reveal code { + font-family: monospace; + text-transform: none; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tbody tr:last-child th, +.reveal table tbody tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; + font-size: smaller; } + +.reveal sub { + vertical-align: sub; + font-size: smaller; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #902A9D; + text-decoration: underline #902A9D solid; + -webkit-text-decoration: underline #902A9D solid; + -moz-text-decoration: underline #902A9D solid; + -webkit-transition: color .15s ease; + -moz-transition: color .15s ease; + transition: color .15s ease; } + +.reveal a:hover { + color: #902A9D; + text-shadow: none; + border: none; + text-decoration: underline #902A9D solid; + -webkit-text-decoration: underline #902A9D solid; + -moz-text-decoration: underline #902A9D solid; + -webkit-transition: color 0.15s ease; + -moz-transition: color 0.15s ease; + transition: color 0.15s ease;} + +.reveal .roll span:after { + color: #f9fafb; + background: #006ba6; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #3F4444; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all .15s linear; + -moz-transition: all .15s linear; + transition: all .15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #004F59; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls { + color: #00BB31; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); + color: #00BB31; + height: .5rem; } + +.reveal .progress span { + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +.reveal footer { + position: fixed; + height: 26px; + width: 100%; + bottom: 15px; + left: 0; + z-index: 10; + font-size: 35%; + text-align: left; + background-repeat: no-repeat; + background-size: auto 74%; + background-position: 7px 0; + font-family: "Source Sans Pro", Helvetica, sans-serif; +} +.reveal footer .copyright { + margin:5px; + display: flex; + flex-direction: row; + justify-content: start; + align-items: center; +} +.reveal footer .copyright * { + vertical-align: middle; +} + +.reveal footer .copyright p { + margin: .3em .3em; +} +.reveal footer span {color: #3F4444;} + +section *, +body .reveal .slides section .fragment { + transition-delay: 0s; + -webkit-transition-delay: 0s; + transition: all 0.4s ease; + -webkit-transition: all 0.4s ease; +} + +section .row:before, +section .row:after { + content: ""; + display: table; + clear: both; +} + +section .row { + margin: 0.15em 0em; +} + +section .row *[class*='col-'] { + box-sizing: border-box; + position: relative; + left: 0; + float: left; + min-height: 1px; + padding: 0em 0.15em; +} + +/*for tables*/ +td { + font-size: 0.6em !important; + text-align: center !important; +} +th { + font-size: 0.7em !important; + text-align: center !important; +} + +.row-flex { + display: flex; + justify-content: stretch; +} + +.table-vert td, +.table-vert th { + border-right: solid 1px #d2d2d2; + border-left: solid 1px #d2d2d2; +} + +.table-leftalign td { + font-size: 0.6em !important; + text-align: left !important; +} +.table-leftalign th { + font-size: 0.6em !important; + text-align: left !important; +} + +.no-top td, +.no-top th { + border-top:0 none !important; +} +.no-bottom td, +.no-bottom th { + border-bottom:0 none !important; +} + +.vert-align { + display: flex; + flex-direction: column; + justify-content: center; +} + +.col-05 { width: 0.5%; } +.col-1 { width: 1%; } +.col-2 { width: 2%; } +.col-3 { width: 3%; } +.col-4 { width: 4%; } +.col-5 { width: 5%; } +.col-6 { width: 6%; } +.col-7 { width: 7%; } +.col-8 { width: 8%; } +.col-9 { width: 9%; } +.col-10 { width: 10%; } +.col-11 { width: 11%; } +.col-12 { width: 12%; } +.col-13 { width: 13%; } +.col-14 { width: 14%; } +.col-15 { width: 15%; } +.col-16 { width: 16%; } +.col-17 { width: 17%; } +.col-18 { width: 18%; } +.col-19 { width: 19%; } +.col-20 { width: 20%; } +.col-21 { width: 21%; } +.col-22 { width: 22%; } +.col-23 { width: 23%; } +.col-24 { width: 24%; } +.col-25 { width: 25%; } +.col-26 { width: 26%; } +.col-27 { width: 27%; } +.col-28 { width: 28%; } +.col-29 { width: 29%; } +.col-30 { width: 30%; } +.col-31 { width: 31%; } +.col-32 { width: 32%; } +.col-33 { width: 33.33%; } +.col-34 { width: 34%; } +.col-35 { width: 35%; } +.col-36 { width: 36%; } +.col-37 { width: 37%; } +.col-38 { width: 38%; } +.col-39 { width: 39%; } +.col-40 { width: 40%; } +.col-41 { width: 41%; } +.col-42 { width: 42%; } +.col-43 { width: 43%; } +.col-44 { width: 44%; } +.col-45 { width: 45%; } +.col-46 { width: 46%; } +.col-47 { width: 47%; } +.col-48 { width: 48%; } +.col-49 { width: 49%; } +.col-50 { width: 50%; } +.col-51 { width: 51%; } +.col-52 { width: 52%; } +.col-53 { width: 53%; } +.col-54 { width: 54%; } +.col-55 { width: 55%; } +.col-56 { width: 56%; } +.col-57 { width: 57%; } +.col-58 { width: 58%; } +.col-59 { width: 59%; } +.col-60 { width: 60%; } +.col-61 { width: 61%; } +.col-62 { width: 62%; } +.col-63 { width: 63%; } +.col-64 { width: 64%; } +.col-65 { width: 65%; } +.col-66 { width: 66.66%; } +.col-67 { width: 67%; } +.col-68 { width: 68%; } +.col-69 { width: 69%; } +.col-70 { width: 70%; } +.col-71 { width: 71%; } +.col-72 { width: 72%; } +.col-73 { width: 73%; } +.col-74 { width: 74%; } +.col-75 { width: 75%; } +.col-76 { width: 76%; } +.col-77 { width: 77%; } +.col-78 { width: 78%; } +.col-79 { width: 79%; } +.col-80 { width: 80%; } +.col-81 { width: 81%; } +.col-82 { width: 82%; } +.col-83 { width: 83%; } +.col-84 { width: 84%; } +.col-85 { width: 85%; } +.col-86 { width: 86%; } +.col-87 { width: 87%; } +.col-88 { width: 88%; } +.col-89 { width: 89%; } +.col-90 { width: 90%; } +.col-91 { width: 91%; } +.col-92 { width: 92%; } +.col-93 { width: 93%; } +.col-94 { width: 94%; } +.col-95 { width: 95%; } +.col-96 { width: 96%; } +.col-97 { width: 97%; } +.col-98 { width: 98%; } +.col-99 { width: 99%; } +.col-100 { width: 100%; } + +.push-5 { left: 5% !important; } +.push-10 { left: 10% !important; } +.push-15 { left: 15% !important; } +.push-20 { left: 20% !important; } +.push-25 { left: 25% !important; } +.push-30 { left: 30% !important; } +.push-33 { left: 33.33% !important; } +.push-35 { left: 35% !important; } +.push-40 { left: 40% !important; } +.push-45 { left: 45% !important; } +.push-50 { left: 50% !important; } +.push-60 { left: 60% !important; } +.push-66 { left: 66.66% !important; } +.push-70 { left: 70% !important; } +.push-75 { left: 75% !important; } +.push-80 { left: 80% !important; } +.push-90 { left: 90% !important; } +.push-100 { left: 100% !important; } + +.pull-5 { left: -5% !important; } +.pull-10 { left: -10% !important; } +.pull-15 { left: -15% !important; } +.pull-20 { left: -20% !important; } +.pull-25 { left: -25% !important; } +.pull-30 { left: -30% !important; } +.pull-35 { left: -35% !important; } +.pull-33 { left: -33.33% !important; } +.pull-40 { left: -40% !important; } +.pull-45 { left: -45% !important; } +.pull-50 { left: -50% !important; } +.pull-60 { left: -60% !important; } +.pull-66 { left: -66.66% !important; } +.pull-70 { left: -70% !important; } +.pull-75 { left: -75% !important; } +.pull-80 { left: -80% !important; } +.pull-90 { left: -90% !important; } +.pull-100 { left: -100% !important; } + + +.reveal .content-box { + display: flex !important; + flex-direction: column !important; + align-items: center !important; + padding: 1.5em 2em 1em; + background: #000000; + opacity: 0.75;} + +.reveal .content-box h1 { + color: #3399ff; +} + + +.no-margin-top { + margin-top: 0 !important; +} +.no-margin-bottom { + margin-bottom: 0 !important; +} + + +/********************************************* + * PRINT BACKGROUND + *********************************************/ +@media print { + .backgrounds { + background-color: #f9fafb; } } diff --git a/talks/css/theme/index.html b/talks/css/theme/index.html new file mode 100644 index 000000000..593b482e6 --- /dev/null +++ b/talks/css/theme/index.html @@ -0,0 +1,237 @@ + + + + + + +Dependencies — Ryan P. Randall + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + +
    +

    Dependencies

    + +

    Themes are written using Sass to keep things modular and reduce the need for repeated selectors across files. Make sure that you have the reveal.js development environment including the Grunt dependencies installed before proceeding: https://github.com/hakimel/reveal.js#full-setup

    + +

    Creating a Theme

    + +

    To create your own theme, start by duplicating a .scss file in /css/theme/source. It will be automatically compiled by Grunt from Sass to CSS (see the Gruntfile) when you run npm run build -- css-themes.

    + +

    Each theme file does four things in the following order:

    + +
      +
    1. +

      Include /css/theme/template/mixins.scss +Shared utility functions.

      +
    2. +
    3. +

      Include /css/theme/template/settings.scss +Declares a set of custom variables that the template file (step 4) expects. Can be overridden in step 3.

      +
    4. +
    5. +

      Override +This is where you override the default theme. Either by specifying variables (see settings.scss for reference) or by adding any selectors and styles you please.

      +
    6. +
    7. +

      Include /css/theme/template/theme.scss +The template theme file which will generate final CSS output based on the currently defined variables.

      +
    8. +
    + +
    + + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + diff --git a/talks/css/theme/isu.css b/talks/css/theme/isu.css new file mode 100644 index 000000000..43f1299e7 --- /dev/null +++ b/talks/css/theme/isu.css @@ -0,0 +1,548 @@ +/** + * White theme for reveal.js. This is the opposite of the 'black' theme. + * + * By Hakim El Hattab, http://hakim.se + */ +@import url('https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@400;700&display=swap'); +section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 { + color: #f9fafb; } + +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #f9fafb; + background-color: #f9fafb; } + +.reveal { + font-family: "Roboto Slab", Helvetica, sans-serif; + font-size: 34px /* 38px */; + font-weight: normal; + color: #3F4444; } + +::selection { + color: #f9fafb; + background: #d4441c; + text-shadow: none; } + +::-moz-selection { + color: #f9fafb; + background: #d4441c; + text-shadow: none; } + +.reveal .slides section, +.reveal .slides section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #333333; + font-family: "Roboto Slab", Helvetica, sans-serif; + font-weight: 600; + line-height: 1.2; + letter-spacing: normal; + text-transform: none; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { +/* font-size: 2.5em; } */ + font-size: 2.2em; } + +.reveal h2 { + font-size: 1.3em /* 1.6em; */ } + +.reveal h3 { + font-size: 1.1 /* 1.3em; */ } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: none; } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } + +.reveal code { + font-family: monospace; + text-transform: none; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tbody tr:last-child th, +.reveal table tbody tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; + font-size: smaller; } + +.reveal sub { + vertical-align: sub; + font-size: smaller; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #b82b00; + text-decoration: underline #b82b00 solid; + -webkit-text-decoration: underline #b82b00 solid; + -moz-text-decoration: underline #b82b00 solid; + -webkit-transition: color .15s ease; + -moz-transition: color .15s ease; + transition: color .15s ease; } + +.reveal a:hover { + color: #d4441c; + text-shadow: none; + border: none; + text-decoration: underline #d4441c solid; + -webkit-text-decoration: underline #d4441c solid; + -moz-text-decoration: underline #d4441c solid; + -webkit-transition: color 0.15s ease; + -moz-transition: color 0.15s ease; + transition: color 0.15s ease;} + +.reveal .roll span:after { + color: #f9fafb; + background: d4441c; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #3F4444; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all .15s linear; + -moz-transition: all .15s linear; + transition: all .15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #b82b00; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls { + color: #d4441c; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: #828282; + color: #f47920; + height: .6rem; } + +.reveal .progress span { + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +.reveal footer { + position: fixed; + height: 26px; + width: 100%; + bottom: 15px; + left: 0; + z-index: 10; + font-size: 35%; + text-align:left; + background-repeat: no-repeat; + background-size: auto 74%; + background-position: 7px 0; + font-family: "Roboto Slab", Helvetica, sans-serif; +} +.reveal footer .copyright { + margin:5px; + display: flex; + flex-direction: row; + justify-content: start; + align-items: center; +} +.reveal footer .copyright * { + vertical-align: middle; +} + +.reveal footer .copyright p { + margin: .3em .3em; +} +.reveal footer span {color: #3F4444;} + +section *, +body .reveal .slides section .fragment { + transition-delay: 0s; + -webkit-transition-delay: 0s; + transition: all 0.4s ease; + -webkit-transition: all 0.4s ease; +} + +section .row:before, +section .row:after { + content: ""; + display: table; + clear: both; +} + +section .row { + margin: 0.15em 0em; +} + +section .row *[class*='col-'] { + box-sizing: border-box; + position: relative; + left: 0; + float: left; + min-height: 1px; + padding: 0em 0.15em; +} + +/*for tables*/ +td { + font-size: 0.6em !important; + text-align: center !important; +} +th { + font-size: 0.7em !important; + text-align: center !important; +} + +.row-flex { + display: flex; + justify-content: stretch; +} + +.table-vert td, +.table-vert th { + border-right: solid 1px #d2d2d2; + border-left: solid 1px #d2d2d2; +} + +.table-leftalign td { + font-size: 0.6em !important; + text-align: left !important; +} +.table-leftalign th { + font-size: 0.6em !important; + text-align: left !important; +} + +.no-top td, +.no-top th { + border-top:0 none !important; +} +.no-bottom td, +.no-bottom th { + border-bottom:0 none !important; +} + +.vert-align { + display: flex; + flex-direction: column; + justify-content: center; +} + +.col-05 { width: 0.5%; } +.col-1 { width: 1%; } +.col-2 { width: 2%; } +.col-3 { width: 3%; } +.col-4 { width: 4%; } +.col-5 { width: 5%; } +.col-6 { width: 6%; } +.col-7 { width: 7%; } +.col-8 { width: 8%; } +.col-9 { width: 9%; } +.col-10 { width: 10%; } +.col-11 { width: 11%; } +.col-12 { width: 12%; } +.col-13 { width: 13%; } +.col-14 { width: 14%; } +.col-15 { width: 15%; } +.col-16 { width: 16%; } +.col-17 { width: 17%; } +.col-18 { width: 18%; } +.col-19 { width: 19%; } +.col-20 { width: 20%; } +.col-21 { width: 21%; } +.col-22 { width: 22%; } +.col-23 { width: 23%; } +.col-24 { width: 24%; } +.col-25 { width: 25%; } +.col-26 { width: 26%; } +.col-27 { width: 27%; } +.col-28 { width: 28%; } +.col-29 { width: 29%; } +.col-30 { width: 30%; } +.col-31 { width: 31%; } +.col-32 { width: 32%; } +.col-33 { width: 33.33%; } +.col-34 { width: 34%; } +.col-35 { width: 35%; } +.col-36 { width: 36%; } +.col-37 { width: 37%; } +.col-38 { width: 38%; } +.col-39 { width: 39%; } +.col-40 { width: 40%; } +.col-41 { width: 41%; } +.col-42 { width: 42%; } +.col-43 { width: 43%; } +.col-44 { width: 44%; } +.col-45 { width: 45%; } +.col-46 { width: 46%; } +.col-47 { width: 47%; } +.col-48 { width: 48%; } +.col-49 { width: 49%; } +.col-50 { width: 50%; } +.col-51 { width: 51%; } +.col-52 { width: 52%; } +.col-53 { width: 53%; } +.col-54 { width: 54%; } +.col-55 { width: 55%; } +.col-56 { width: 56%; } +.col-57 { width: 57%; } +.col-58 { width: 58%; } +.col-59 { width: 59%; } +.col-60 { width: 60%; } +.col-61 { width: 61%; } +.col-62 { width: 62%; } +.col-63 { width: 63%; } +.col-64 { width: 64%; } +.col-65 { width: 65%; } +.col-66 { width: 66.66%; } +.col-67 { width: 67%; } +.col-68 { width: 68%; } +.col-69 { width: 69%; } +.col-70 { width: 70%; } +.col-71 { width: 71%; } +.col-72 { width: 72%; } +.col-73 { width: 73%; } +.col-74 { width: 74%; } +.col-75 { width: 75%; } +.col-76 { width: 76%; } +.col-77 { width: 77%; } +.col-78 { width: 78%; } +.col-79 { width: 79%; } +.col-80 { width: 80%; } +.col-81 { width: 81%; } +.col-82 { width: 82%; } +.col-83 { width: 83%; } +.col-84 { width: 84%; } +.col-85 { width: 85%; } +.col-86 { width: 86%; } +.col-87 { width: 87%; } +.col-88 { width: 88%; } +.col-89 { width: 89%; } +.col-90 { width: 90%; } +.col-91 { width: 91%; } +.col-92 { width: 92%; } +.col-93 { width: 93%; } +.col-94 { width: 94%; } +.col-95 { width: 95%; } +.col-96 { width: 96%; } +.col-97 { width: 97%; } +.col-98 { width: 98%; } +.col-99 { width: 99%; } +.col-100 { width: 100%; } + +.push-5 { left: 5% !important; } +.push-10 { left: 10% !important; } +.push-15 { left: 15% !important; } +.push-20 { left: 20% !important; } +.push-25 { left: 25% !important; } +.push-30 { left: 30% !important; } +.push-33 { left: 33.33% !important; } +.push-35 { left: 35% !important; } +.push-40 { left: 40% !important; } +.push-45 { left: 45% !important; } +.push-50 { left: 50% !important; } +.push-60 { left: 60% !important; } +.push-66 { left: 66.66% !important; } +.push-70 { left: 70% !important; } +.push-75 { left: 75% !important; } +.push-80 { left: 80% !important; } +.push-90 { left: 90% !important; } +.push-100 { left: 100% !important; } + +.pull-5 { left: -5% !important; } +.pull-10 { left: -10% !important; } +.pull-15 { left: -15% !important; } +.pull-20 { left: -20% !important; } +.pull-25 { left: -25% !important; } +.pull-30 { left: -30% !important; } +.pull-35 { left: -35% !important; } +.pull-33 { left: -33.33% !important; } +.pull-40 { left: -40% !important; } +.pull-45 { left: -45% !important; } +.pull-50 { left: -50% !important; } +.pull-60 { left: -60% !important; } +.pull-66 { left: -66.66% !important; } +.pull-70 { left: -70% !important; } +.pull-75 { left: -75% !important; } +.pull-80 { left: -80% !important; } +.pull-90 { left: -90% !important; } +.pull-100 { left: -100% !important; } + + +.reveal .content-box { + display: flex !important; + flex-direction: column !important; + align-items: center !important; + padding: 1.5em 2em 1em; + background: #000000; + opacity: 0.75;} + +.reveal .content-box h1 { + color: #f47920; +} + + +.no-margin-top { + margin-top: 0 !important; +} +.no-margin-bottom { + margin-bottom: 0 !important; +} + + +/********************************************* + * PRINT BACKGROUND + *********************************************/ +@media print { + .backgrounds { + background-color: #f9fafb; } } diff --git a/talks/css/theme/league.css b/talks/css/theme/league.css new file mode 100755 index 000000000..f8fba4da2 --- /dev/null +++ b/talks/css/theme/league.css @@ -0,0 +1,279 @@ +/** + * League theme for reveal.js. + * + * This was the default theme pre-3.0.0. + * + * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se + */ +@import url(../../lib/font/league-gothic/league-gothic.css); +@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #1c1e20; + background: -moz-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%); + background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #555a5f), color-stop(100%, #1c1e20)); + background: -webkit-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%); + background: -o-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%); + background: -ms-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%); + background: radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%); + background-color: #2b2b2b; } + +.reveal { + font-family: "Lato", sans-serif; + font-size: 40px; + font-weight: normal; + color: #eee; } + +::selection { + color: #fff; + background: #FF5E99; + text-shadow: none; } + +::-moz-selection { + color: #fff; + background: #FF5E99; + text-shadow: none; } + +.reveal .slides section, +.reveal .slides section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #eee; + font-family: "League Gothic", Impact, sans-serif; + font-weight: normal; + line-height: 1.2; + letter-spacing: normal; + text-transform: uppercase; + text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); + word-wrap: break-word; } + +.reveal h1 { + font-size: 3.77em; } + +.reveal h2 { + font-size: 2.11em; } + +.reveal h3 { + font-size: 1.55em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15); } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); } + +.reveal code { + font-family: monospace; + text-transform: none; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tbody tr:last-child th, +.reveal table tbody tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; + font-size: smaller; } + +.reveal sub { + vertical-align: sub; + font-size: smaller; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #13DAEC; + text-decoration: none; + -webkit-transition: color .15s ease; + -moz-transition: color .15s ease; + transition: color .15s ease; } + +.reveal a:hover { + color: #71e9f4; + text-shadow: none; + border: none; } + +.reveal .roll span:after { + color: #fff; + background: #0d99a5; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #eee; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all .15s linear; + -moz-transition: all .15s linear; + transition: all .15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #13DAEC; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls { + color: #13DAEC; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); + color: #13DAEC; } + +.reveal .progress span { + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +/********************************************* + * PRINT BACKGROUND + *********************************************/ +@media print { + .backgrounds { + background-color: #2b2b2b; } } diff --git a/talks/css/theme/moon.css b/talks/css/theme/moon.css new file mode 100755 index 000000000..d18f52603 --- /dev/null +++ b/talks/css/theme/moon.css @@ -0,0 +1,277 @@ +/** + * Solarized Dark theme for reveal.js. + * Author: Achim Staebler + */ +@import url(../../lib/font/league-gothic/league-gothic.css); +@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); +/** + * Solarized colors by Ethan Schoonover + */ +html * { + color-profile: sRGB; + rendering-intent: auto; } + +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #002b36; + background-color: #002b36; } + +.reveal { + font-family: "Lato", sans-serif; + font-size: 40px; + font-weight: normal; + color: #93a1a1; } + +::selection { + color: #fff; + background: #d33682; + text-shadow: none; } + +::-moz-selection { + color: #fff; + background: #d33682; + text-shadow: none; } + +.reveal .slides section, +.reveal .slides section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #eee8d5; + font-family: "League Gothic", Impact, sans-serif; + font-weight: normal; + line-height: 1.2; + letter-spacing: normal; + text-transform: uppercase; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 3.77em; } + +.reveal h2 { + font-size: 2.11em; } + +.reveal h3 { + font-size: 1.55em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: none; } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); } + +.reveal code { + font-family: monospace; + text-transform: none; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tbody tr:last-child th, +.reveal table tbody tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; + font-size: smaller; } + +.reveal sub { + vertical-align: sub; + font-size: smaller; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #268bd2; + text-decoration: none; + -webkit-transition: color .15s ease; + -moz-transition: color .15s ease; + transition: color .15s ease; } + +.reveal a:hover { + color: #78b9e6; + text-shadow: none; + border: none; } + +.reveal .roll span:after { + color: #fff; + background: #1a6091; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #93a1a1; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all .15s linear; + -moz-transition: all .15s linear; + transition: all .15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #268bd2; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls { + color: #268bd2; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); + color: #268bd2; } + +.reveal .progress span { + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +/********************************************* + * PRINT BACKGROUND + *********************************************/ +@media print { + .backgrounds { + background-color: #002b36; } } diff --git a/talks/css/theme/night.css b/talks/css/theme/night.css new file mode 100755 index 000000000..f5ccb522d --- /dev/null +++ b/talks/css/theme/night.css @@ -0,0 +1,271 @@ +/** + * Black theme for reveal.js. + * + * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se + */ +@import url(https://fonts.googleapis.com/css?family=Montserrat:700); +@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic,700italic); +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #111; + background-color: #111; } + +.reveal { + font-family: "Open Sans", sans-serif; + font-size: 40px; + font-weight: normal; + color: #eee; } + +::selection { + color: #fff; + background: #e7ad52; + text-shadow: none; } + +::-moz-selection { + color: #fff; + background: #e7ad52; + text-shadow: none; } + +.reveal .slides section, +.reveal .slides section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #eee; + font-family: "Montserrat", Impact, sans-serif; + font-weight: normal; + line-height: 1.2; + letter-spacing: -0.03em; + text-transform: none; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 3.77em; } + +.reveal h2 { + font-size: 2.11em; } + +.reveal h3 { + font-size: 1.55em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: none; } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); } + +.reveal code { + font-family: monospace; + text-transform: none; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tbody tr:last-child th, +.reveal table tbody tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; + font-size: smaller; } + +.reveal sub { + vertical-align: sub; + font-size: smaller; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #e7ad52; + text-decoration: none; + -webkit-transition: color .15s ease; + -moz-transition: color .15s ease; + transition: color .15s ease; } + +.reveal a:hover { + color: #f3d7ac; + text-shadow: none; + border: none; } + +.reveal .roll span:after { + color: #fff; + background: #d08a1d; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #eee; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all .15s linear; + -moz-transition: all .15s linear; + transition: all .15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #e7ad52; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls { + color: #e7ad52; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); + color: #e7ad52; } + +.reveal .progress span { + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +/********************************************* + * PRINT BACKGROUND + *********************************************/ +@media print { + .backgrounds { + background-color: #111; } } diff --git a/talks/css/theme/serif.css b/talks/css/theme/serif.css new file mode 100755 index 000000000..6514a6fc2 --- /dev/null +++ b/talks/css/theme/serif.css @@ -0,0 +1,273 @@ +/** + * A simple theme for reveal.js presentations, similar + * to the default theme. The accent color is brown. + * + * This theme is Copyright (C) 2012-2013 Owen Versteeg, http://owenversteeg.com - it is MIT licensed. + */ +.reveal a { + line-height: 1.3em; } + +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #F0F1EB; + background-color: #F0F1EB; } + +.reveal { + font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif; + font-size: 40px; + font-weight: normal; + color: #000; } + +::selection { + color: #fff; + background: #26351C; + text-shadow: none; } + +::-moz-selection { + color: #fff; + background: #26351C; + text-shadow: none; } + +.reveal .slides section, +.reveal .slides section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #383D3D; + font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif; + font-weight: normal; + line-height: 1.2; + letter-spacing: normal; + text-transform: none; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 3.77em; } + +.reveal h2 { + font-size: 2.11em; } + +.reveal h3 { + font-size: 1.55em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: none; } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); } + +.reveal code { + font-family: monospace; + text-transform: none; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tbody tr:last-child th, +.reveal table tbody tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; + font-size: smaller; } + +.reveal sub { + vertical-align: sub; + font-size: smaller; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #51483D; + text-decoration: none; + -webkit-transition: color .15s ease; + -moz-transition: color .15s ease; + transition: color .15s ease; } + +.reveal a:hover { + color: #8b7c69; + text-shadow: none; + border: none; } + +.reveal .roll span:after { + color: #fff; + background: #25211c; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #000; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all .15s linear; + -moz-transition: all .15s linear; + transition: all .15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #51483D; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls { + color: #51483D; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); + color: #51483D; } + +.reveal .progress span { + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +/********************************************* + * PRINT BACKGROUND + *********************************************/ +@media print { + .backgrounds { + background-color: #F0F1EB; } } diff --git a/talks/css/theme/simple.css b/talks/css/theme/simple.css new file mode 100755 index 000000000..a7a29a640 --- /dev/null +++ b/talks/css/theme/simple.css @@ -0,0 +1,276 @@ +/** + * A simple theme for reveal.js presentations, similar + * to the default theme. The accent color is darkblue. + * + * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed. + * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se + */ +@import url(https://fonts.googleapis.com/css?family=News+Cycle:400,700); +@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); +section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 { + color: #fff; } + +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #fff; + background-color: #fff; } + +.reveal { + font-family: "Lato", sans-serif; + font-size: 40px; + font-weight: normal; + color: #000; } + +::selection { + color: #fff; + background: rgba(0, 0, 0, 0.99); + text-shadow: none; } + +::-moz-selection { + color: #fff; + background: rgba(0, 0, 0, 0.99); + text-shadow: none; } + +.reveal .slides section, +.reveal .slides section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #000; + font-family: "News Cycle", Impact, sans-serif; + font-weight: normal; + line-height: 1.2; + letter-spacing: normal; + text-transform: none; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 3.77em; } + +.reveal h2 { + font-size: 2.11em; } + +.reveal h3 { + font-size: 1.55em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: none; } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); } + +.reveal code { + font-family: monospace; + text-transform: none; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tbody tr:last-child th, +.reveal table tbody tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; + font-size: smaller; } + +.reveal sub { + vertical-align: sub; + font-size: smaller; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #00008B; + text-decoration: none; + -webkit-transition: color .15s ease; + -moz-transition: color .15s ease; + transition: color .15s ease; } + +.reveal a:hover { + color: #0000f1; + text-shadow: none; + border: none; } + +.reveal .roll span:after { + color: #fff; + background: #00003f; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #000; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all .15s linear; + -moz-transition: all .15s linear; + transition: all .15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #00008B; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls { + color: #00008B; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); + color: #00008B; } + +.reveal .progress span { + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +/********************************************* + * PRINT BACKGROUND + *********************************************/ +@media print { + .backgrounds { + background-color: #fff; } } diff --git a/talks/css/theme/sky.css b/talks/css/theme/sky.css new file mode 100755 index 000000000..d8734c9c2 --- /dev/null +++ b/talks/css/theme/sky.css @@ -0,0 +1,280 @@ +/** + * Sky theme for reveal.js. + * + * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se + */ +@import url(https://fonts.googleapis.com/css?family=Quicksand:400,700,400italic,700italic); +@import url(https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700); +.reveal a { + line-height: 1.3em; } + +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #add9e4; + background: -moz-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%); + background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #f7fbfc), color-stop(100%, #add9e4)); + background: -webkit-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%); + background: -o-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%); + background: -ms-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%); + background: radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%); + background-color: #f7fbfc; } + +.reveal { + font-family: "Open Sans", sans-serif; + font-size: 40px; + font-weight: normal; + color: #333; } + +::selection { + color: #fff; + background: #134674; + text-shadow: none; } + +::-moz-selection { + color: #fff; + background: #134674; + text-shadow: none; } + +.reveal .slides section, +.reveal .slides section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #333; + font-family: "Quicksand", sans-serif; + font-weight: normal; + line-height: 1.2; + letter-spacing: -0.08em; + text-transform: uppercase; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 3.77em; } + +.reveal h2 { + font-size: 2.11em; } + +.reveal h3 { + font-size: 1.55em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: none; } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); } + +.reveal code { + font-family: monospace; + text-transform: none; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tbody tr:last-child th, +.reveal table tbody tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; + font-size: smaller; } + +.reveal sub { + vertical-align: sub; + font-size: smaller; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #3b759e; + text-decoration: none; + -webkit-transition: color .15s ease; + -moz-transition: color .15s ease; + transition: color .15s ease; } + +.reveal a:hover { + color: #74a7cb; + text-shadow: none; + border: none; } + +.reveal .roll span:after { + color: #fff; + background: #264c66; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #333; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all .15s linear; + -moz-transition: all .15s linear; + transition: all .15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #3b759e; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls { + color: #3b759e; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); + color: #3b759e; } + +.reveal .progress span { + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +/********************************************* + * PRINT BACKGROUND + *********************************************/ +@media print { + .backgrounds { + background-color: #f7fbfc; } } diff --git a/talks/css/theme/solarized.css b/talks/css/theme/solarized.css new file mode 100755 index 000000000..f1a2b9e39 --- /dev/null +++ b/talks/css/theme/solarized.css @@ -0,0 +1,277 @@ +/** + * Solarized Light theme for reveal.js. + * Author: Achim Staebler + */ +@import url(../../lib/font/league-gothic/league-gothic.css); +@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); +/** + * Solarized colors by Ethan Schoonover + */ +html * { + color-profile: sRGB; + rendering-intent: auto; } + +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #fdf6e3; + background-color: #fdf6e3; } + +.reveal { + font-family: "Lato", sans-serif; + font-size: 40px; + font-weight: normal; + color: #657b83; } + +::selection { + color: #fff; + background: #d33682; + text-shadow: none; } + +::-moz-selection { + color: #fff; + background: #d33682; + text-shadow: none; } + +.reveal .slides section, +.reveal .slides section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #586e75; + font-family: "League Gothic", Impact, sans-serif; + font-weight: normal; + line-height: 1.2; + letter-spacing: normal; + text-transform: uppercase; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 3.77em; } + +.reveal h2 { + font-size: 2.11em; } + +.reveal h3 { + font-size: 1.55em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: none; } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); } + +.reveal code { + font-family: monospace; + text-transform: none; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tbody tr:last-child th, +.reveal table tbody tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; + font-size: smaller; } + +.reveal sub { + vertical-align: sub; + font-size: smaller; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #268bd2; + text-decoration: none; + -webkit-transition: color .15s ease; + -moz-transition: color .15s ease; + transition: color .15s ease; } + +.reveal a:hover { + color: #78b9e6; + text-shadow: none; + border: none; } + +.reveal .roll span:after { + color: #fff; + background: #1a6091; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #657b83; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all .15s linear; + -moz-transition: all .15s linear; + transition: all .15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #268bd2; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls { + color: #268bd2; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); + color: #268bd2; } + +.reveal .progress span { + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +/********************************************* + * PRINT BACKGROUND + *********************************************/ +@media print { + .backgrounds { + background-color: #fdf6e3; } } diff --git a/talks/css/theme/source/beige.scss b/talks/css/theme/source/beige.scss new file mode 100755 index 000000000..5564f5389 --- /dev/null +++ b/talks/css/theme/source/beige.scss @@ -0,0 +1,39 @@ +/** + * Beige theme for reveal.js. + * + * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se + */ + + +// Default mixins and settings ----------------- +@import "../template/mixins"; +@import "../template/settings"; +// --------------------------------------------- + + + +// Include theme-specific fonts +@import url(../../lib/font/league-gothic/league-gothic.css); +@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); + + +// Override theme settings (see ../template/settings.scss) +$mainColor: #333; +$headingColor: #333; +$headingTextShadow: none; +$backgroundColor: #f7f3de; +$linkColor: #8b743d; +$linkColorHover: lighten( $linkColor, 20% ); +$selectionBackgroundColor: rgba(79, 64, 28, 0.99); +$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15); + +// Background generator +@mixin bodyBackground() { + @include radial-gradient( rgba(247,242,211,1), rgba(255,255,255,1) ); +} + + + +// Theme template ------------------------------ +@import "../template/theme"; +// --------------------------------------------- \ No newline at end of file diff --git a/talks/css/theme/source/black.scss b/talks/css/theme/source/black.scss new file mode 100755 index 000000000..4720c8abe --- /dev/null +++ b/talks/css/theme/source/black.scss @@ -0,0 +1,49 @@ +/** + * Black theme for reveal.js. This is the opposite of the 'white' theme. + * + * By Hakim El Hattab, http://hakim.se + */ + + +// Default mixins and settings ----------------- +@import "../template/mixins"; +@import "../template/settings"; +// --------------------------------------------- + + +// Include theme-specific fonts +@import url(../../lib/font/source-sans-pro/source-sans-pro.css); + + +// Override theme settings (see ../template/settings.scss) +$backgroundColor: #191919; + +$mainColor: #fff; +$headingColor: #fff; + +$mainFontSize: 42px; +$mainFont: 'Source Sans Pro', Helvetica, sans-serif; +$headingFont: 'Source Sans Pro', Helvetica, sans-serif; +$headingTextShadow: none; +$headingLetterSpacing: normal; +$headingTextTransform: uppercase; +$headingFontWeight: 600; +$linkColor: #42affa; +$linkColorHover: lighten( $linkColor, 15% ); +$selectionBackgroundColor: lighten( $linkColor, 25% ); + +$heading1Size: 2.5em; +$heading2Size: 1.6em; +$heading3Size: 1.3em; +$heading4Size: 1.0em; + +section.has-light-background { + &, h1, h2, h3, h4, h5, h6 { + color: #222; + } +} + + +// Theme template ------------------------------ +@import "../template/theme"; +// --------------------------------------------- \ No newline at end of file diff --git a/talks/css/theme/source/blood.scss b/talks/css/theme/source/blood.scss new file mode 100755 index 000000000..4533fc063 --- /dev/null +++ b/talks/css/theme/source/blood.scss @@ -0,0 +1,78 @@ +/** + * Blood theme for reveal.js + * Author: Walther http://github.com/Walther + * + * Designed to be used with highlight.js theme + * "monokai_sublime.css" available from + * https://github.com/isagalaev/highlight.js/ + * + * For other themes, change $codeBackground accordingly. + * + */ + + // Default mixins and settings ----------------- +@import "../template/mixins"; +@import "../template/settings"; +// --------------------------------------------- + +// Include theme-specific fonts + +@import url(https://fonts.googleapis.com/css?family=Ubuntu:300,700,300italic,700italic); + +// Colors used in the theme +$blood: #a23; +$coal: #222; +$codeBackground: #23241f; + +$backgroundColor: $coal; + +// Main text +$mainFont: Ubuntu, 'sans-serif'; +$mainColor: #eee; + +// Headings +$headingFont: Ubuntu, 'sans-serif'; +$headingTextShadow: 2px 2px 2px $coal; + +// h1 shadow, borrowed humbly from +// (c) Default theme by Hakim El Hattab +$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15); + +// Links +$linkColor: $blood; +$linkColorHover: lighten( $linkColor, 20% ); + +// Text selection +$selectionBackgroundColor: $blood; +$selectionColor: #fff; + + +// Theme template ------------------------------ +@import "../template/theme"; +// --------------------------------------------- + +// some overrides after theme template import + +.reveal p { + font-weight: 300; + text-shadow: 1px 1px $coal; +} + +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + font-weight: 700; +} + +.reveal p code { + background-color: $codeBackground; + display: inline-block; + border-radius: 7px; +} + +.reveal small code { + vertical-align: baseline; +} \ No newline at end of file diff --git a/talks/css/theme/source/league.scss b/talks/css/theme/source/league.scss new file mode 100755 index 000000000..46ea04a0e --- /dev/null +++ b/talks/css/theme/source/league.scss @@ -0,0 +1,34 @@ +/** + * League theme for reveal.js. + * + * This was the default theme pre-3.0.0. + * + * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se + */ + + +// Default mixins and settings ----------------- +@import "../template/mixins"; +@import "../template/settings"; +// --------------------------------------------- + + + +// Include theme-specific fonts +@import url(../../lib/font/league-gothic/league-gothic.css); +@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); + +// Override theme settings (see ../template/settings.scss) +$headingTextShadow: 0px 0px 6px rgba(0,0,0,0.2); +$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15); + +// Background generator +@mixin bodyBackground() { + @include radial-gradient( rgba(28,30,32,1), rgba(85,90,95,1) ); +} + + + +// Theme template ------------------------------ +@import "../template/theme"; +// --------------------------------------------- \ No newline at end of file diff --git a/talks/css/theme/source/moon.scss b/talks/css/theme/source/moon.scss new file mode 100755 index 000000000..e47e5b562 --- /dev/null +++ b/talks/css/theme/source/moon.scss @@ -0,0 +1,57 @@ +/** + * Solarized Dark theme for reveal.js. + * Author: Achim Staebler + */ + + +// Default mixins and settings ----------------- +@import "../template/mixins"; +@import "../template/settings"; +// --------------------------------------------- + + + +// Include theme-specific fonts +@import url(../../lib/font/league-gothic/league-gothic.css); +@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); + +/** + * Solarized colors by Ethan Schoonover + */ +html * { + color-profile: sRGB; + rendering-intent: auto; +} + +// Solarized colors +$base03: #002b36; +$base02: #073642; +$base01: #586e75; +$base00: #657b83; +$base0: #839496; +$base1: #93a1a1; +$base2: #eee8d5; +$base3: #fdf6e3; +$yellow: #b58900; +$orange: #cb4b16; +$red: #dc322f; +$magenta: #d33682; +$violet: #6c71c4; +$blue: #268bd2; +$cyan: #2aa198; +$green: #859900; + +// Override theme settings (see ../template/settings.scss) +$mainColor: $base1; +$headingColor: $base2; +$headingTextShadow: none; +$backgroundColor: $base03; +$linkColor: $blue; +$linkColorHover: lighten( $linkColor, 20% ); +$selectionBackgroundColor: $magenta; + + + +// Theme template ------------------------------ +@import "../template/theme"; +// --------------------------------------------- diff --git a/talks/css/theme/source/night.scss b/talks/css/theme/source/night.scss new file mode 100755 index 000000000..d49a28256 --- /dev/null +++ b/talks/css/theme/source/night.scss @@ -0,0 +1,34 @@ +/** + * Black theme for reveal.js. + * + * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se + */ + + +// Default mixins and settings ----------------- +@import "../template/mixins"; +@import "../template/settings"; +// --------------------------------------------- + + +// Include theme-specific fonts +@import url(https://fonts.googleapis.com/css?family=Montserrat:700); +@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic,700italic); + + +// Override theme settings (see ../template/settings.scss) +$backgroundColor: #111; + +$mainFont: 'Open Sans', sans-serif; +$linkColor: #e7ad52; +$linkColorHover: lighten( $linkColor, 20% ); +$headingFont: 'Montserrat', Impact, sans-serif; +$headingTextShadow: none; +$headingLetterSpacing: -0.03em; +$headingTextTransform: none; +$selectionBackgroundColor: #e7ad52; + + +// Theme template ------------------------------ +@import "../template/theme"; +// --------------------------------------------- \ No newline at end of file diff --git a/talks/css/theme/source/serif.scss b/talks/css/theme/source/serif.scss new file mode 100755 index 000000000..ec3fcb30b --- /dev/null +++ b/talks/css/theme/source/serif.scss @@ -0,0 +1,35 @@ +/** + * A simple theme for reveal.js presentations, similar + * to the default theme. The accent color is brown. + * + * This theme is Copyright (C) 2012-2013 Owen Versteeg, http://owenversteeg.com - it is MIT licensed. + */ + + +// Default mixins and settings ----------------- +@import "../template/mixins"; +@import "../template/settings"; +// --------------------------------------------- + + + +// Override theme settings (see ../template/settings.scss) +$mainFont: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; +$mainColor: #000; +$headingFont: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; +$headingColor: #383D3D; +$headingTextShadow: none; +$headingTextTransform: none; +$backgroundColor: #F0F1EB; +$linkColor: #51483D; +$linkColorHover: lighten( $linkColor, 20% ); +$selectionBackgroundColor: #26351C; + +.reveal a { + line-height: 1.3em; +} + + +// Theme template ------------------------------ +@import "../template/theme"; +// --------------------------------------------- diff --git a/talks/css/theme/source/simple.scss b/talks/css/theme/source/simple.scss new file mode 100755 index 000000000..394c9cd0d --- /dev/null +++ b/talks/css/theme/source/simple.scss @@ -0,0 +1,43 @@ +/** + * A simple theme for reveal.js presentations, similar + * to the default theme. The accent color is darkblue. + * + * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed. + * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se + */ + + +// Default mixins and settings ----------------- +@import "../template/mixins"; +@import "../template/settings"; +// --------------------------------------------- + + + +// Include theme-specific fonts +@import url(https://fonts.googleapis.com/css?family=News+Cycle:400,700); +@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); + + +// Override theme settings (see ../template/settings.scss) +$mainFont: 'Lato', sans-serif; +$mainColor: #000; +$headingFont: 'News Cycle', Impact, sans-serif; +$headingColor: #000; +$headingTextShadow: none; +$headingTextTransform: none; +$backgroundColor: #fff; +$linkColor: #00008B; +$linkColorHover: lighten( $linkColor, 20% ); +$selectionBackgroundColor: rgba(0, 0, 0, 0.99); + +section.has-dark-background { + &, h1, h2, h3, h4, h5, h6 { + color: #fff; + } +} + + +// Theme template ------------------------------ +@import "../template/theme"; +// --------------------------------------------- \ No newline at end of file diff --git a/talks/css/theme/source/sky.scss b/talks/css/theme/source/sky.scss new file mode 100755 index 000000000..3fee67c5d --- /dev/null +++ b/talks/css/theme/source/sky.scss @@ -0,0 +1,46 @@ +/** + * Sky theme for reveal.js. + * + * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se + */ + + +// Default mixins and settings ----------------- +@import "../template/mixins"; +@import "../template/settings"; +// --------------------------------------------- + + + +// Include theme-specific fonts +@import url(https://fonts.googleapis.com/css?family=Quicksand:400,700,400italic,700italic); +@import url(https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700); + + +// Override theme settings (see ../template/settings.scss) +$mainFont: 'Open Sans', sans-serif; +$mainColor: #333; +$headingFont: 'Quicksand', sans-serif; +$headingColor: #333; +$headingLetterSpacing: -0.08em; +$headingTextShadow: none; +$backgroundColor: #f7fbfc; +$linkColor: #3b759e; +$linkColorHover: lighten( $linkColor, 20% ); +$selectionBackgroundColor: #134674; + +// Fix links so they are not cut off +.reveal a { + line-height: 1.3em; +} + +// Background generator +@mixin bodyBackground() { + @include radial-gradient( #add9e4, #f7fbfc ); +} + + + +// Theme template ------------------------------ +@import "../template/theme"; +// --------------------------------------------- diff --git a/talks/css/theme/source/solarized.scss b/talks/css/theme/source/solarized.scss new file mode 100755 index 000000000..912be56f3 --- /dev/null +++ b/talks/css/theme/source/solarized.scss @@ -0,0 +1,63 @@ +/** + * Solarized Light theme for reveal.js. + * Author: Achim Staebler + */ + + +// Default mixins and settings ----------------- +@import "../template/mixins"; +@import "../template/settings"; +// --------------------------------------------- + + + +// Include theme-specific fonts +@import url(../../lib/font/league-gothic/league-gothic.css); +@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); + + +/** + * Solarized colors by Ethan Schoonover + */ +html * { + color-profile: sRGB; + rendering-intent: auto; +} + +// Solarized colors +$base03: #002b36; +$base02: #073642; +$base01: #586e75; +$base00: #657b83; +$base0: #839496; +$base1: #93a1a1; +$base2: #eee8d5; +$base3: #fdf6e3; +$yellow: #b58900; +$orange: #cb4b16; +$red: #dc322f; +$magenta: #d33682; +$violet: #6c71c4; +$blue: #268bd2; +$cyan: #2aa198; +$green: #859900; + +// Override theme settings (see ../template/settings.scss) +$mainColor: $base00; +$headingColor: $base01; +$headingTextShadow: none; +$backgroundColor: $base3; +$linkColor: $blue; +$linkColorHover: lighten( $linkColor, 20% ); +$selectionBackgroundColor: $magenta; + +// Background generator +// @mixin bodyBackground() { +// @include radial-gradient( rgba($base3,1), rgba(lighten($base3, 20%),1) ); +// } + + + +// Theme template ------------------------------ +@import "../template/theme"; +// --------------------------------------------- diff --git a/talks/css/theme/source/white.scss b/talks/css/theme/source/white.scss new file mode 100755 index 000000000..7f06ffd27 --- /dev/null +++ b/talks/css/theme/source/white.scss @@ -0,0 +1,49 @@ +/** + * White theme for reveal.js. This is the opposite of the 'black' theme. + * + * By Hakim El Hattab, http://hakim.se + */ + + +// Default mixins and settings ----------------- +@import "../template/mixins"; +@import "../template/settings"; +// --------------------------------------------- + + +// Include theme-specific fonts +@import url(../../lib/font/source-sans-pro/source-sans-pro.css); + + +// Override theme settings (see ../template/settings.scss) +$backgroundColor: #fff; + +$mainColor: #222; +$headingColor: #222; + +$mainFontSize: 42px; +$mainFont: 'Source Sans Pro', Helvetica, sans-serif; +$headingFont: 'Source Sans Pro', Helvetica, sans-serif; +$headingTextShadow: none; +$headingLetterSpacing: normal; +$headingTextTransform: uppercase; +$headingFontWeight: 600; +$linkColor: #2a76dd; +$linkColorHover: lighten( $linkColor, 15% ); +$selectionBackgroundColor: lighten( $linkColor, 25% ); + +$heading1Size: 2.5em; +$heading2Size: 1.6em; +$heading3Size: 1.3em; +$heading4Size: 1.0em; + +section.has-dark-background { + &, h1, h2, h3, h4, h5, h6 { + color: #fff; + } +} + + +// Theme template ------------------------------ +@import "../template/theme"; +// --------------------------------------------- \ No newline at end of file diff --git a/talks/css/theme/template/mixins.scss b/talks/css/theme/template/mixins.scss new file mode 100755 index 000000000..e0c560692 --- /dev/null +++ b/talks/css/theme/template/mixins.scss @@ -0,0 +1,29 @@ +@mixin vertical-gradient( $top, $bottom ) { + background: $top; + background: -moz-linear-gradient( top, $top 0%, $bottom 100% ); + background: -webkit-gradient( linear, left top, left bottom, color-stop(0%,$top), color-stop(100%,$bottom) ); + background: -webkit-linear-gradient( top, $top 0%, $bottom 100% ); + background: -o-linear-gradient( top, $top 0%, $bottom 100% ); + background: -ms-linear-gradient( top, $top 0%, $bottom 100% ); + background: linear-gradient( top, $top 0%, $bottom 100% ); +} + +@mixin horizontal-gradient( $top, $bottom ) { + background: $top; + background: -moz-linear-gradient( left, $top 0%, $bottom 100% ); + background: -webkit-gradient( linear, left top, right top, color-stop(0%,$top), color-stop(100%,$bottom) ); + background: -webkit-linear-gradient( left, $top 0%, $bottom 100% ); + background: -o-linear-gradient( left, $top 0%, $bottom 100% ); + background: -ms-linear-gradient( left, $top 0%, $bottom 100% ); + background: linear-gradient( left, $top 0%, $bottom 100% ); +} + +@mixin radial-gradient( $outer, $inner, $type: circle ) { + background: $outer; + background: -moz-radial-gradient( center, $type cover, $inner 0%, $outer 100% ); + background: -webkit-gradient( radial, center center, 0px, center center, 100%, color-stop(0%,$inner), color-stop(100%,$outer) ); + background: -webkit-radial-gradient( center, $type cover, $inner 0%, $outer 100% ); + background: -o-radial-gradient( center, $type cover, $inner 0%, $outer 100% ); + background: -ms-radial-gradient( center, $type cover, $inner 0%, $outer 100% ); + background: radial-gradient( center, $type cover, $inner 0%, $outer 100% ); +} \ No newline at end of file diff --git a/talks/css/theme/template/settings.scss b/talks/css/theme/template/settings.scss new file mode 100755 index 000000000..5a917f862 --- /dev/null +++ b/talks/css/theme/template/settings.scss @@ -0,0 +1,45 @@ +// Base settings for all themes that can optionally be +// overridden by the super-theme + +// Background of the presentation +$backgroundColor: #2b2b2b; + +// Primary/body text +$mainFont: 'Lato', sans-serif; +$mainFontSize: 40px; +$mainColor: #eee; + +// Vertical spacing between blocks of text +$blockMargin: 20px; + +// Headings +$headingMargin: 0 0 $blockMargin 0; +$headingFont: 'League Gothic', Impact, sans-serif; +$headingColor: #eee; +$headingLineHeight: 1.2; +$headingLetterSpacing: normal; +$headingTextTransform: uppercase; +$headingTextShadow: none; +$headingFontWeight: normal; +$heading1TextShadow: $headingTextShadow; + +$heading1Size: 3.77em; +$heading2Size: 2.11em; +$heading3Size: 1.55em; +$heading4Size: 1.00em; + +$codeFont: monospace; + +// Links and actions +$linkColor: #13DAEC; +$linkColorHover: lighten( $linkColor, 20% ); + +// Text selection +$selectionBackgroundColor: #FF5E99; +$selectionColor: #fff; + +// Generates the presentation background, can be overridden +// to return a background image or gradient +@mixin bodyBackground() { + background: $backgroundColor; +} diff --git a/talks/css/theme/template/theme.scss b/talks/css/theme/template/theme.scss new file mode 100755 index 000000000..9ccfaf511 --- /dev/null +++ b/talks/css/theme/template/theme.scss @@ -0,0 +1,325 @@ +// Base theme template for reveal.js + +/********************************************* + * GLOBAL STYLES + *********************************************/ + +body { + @include bodyBackground(); + background-color: $backgroundColor; +} + +.reveal { + font-family: $mainFont; + font-size: $mainFontSize; + font-weight: normal; + color: $mainColor; +} + +::selection { + color: $selectionColor; + background: $selectionBackgroundColor; + text-shadow: none; +} + +::-moz-selection { + color: $selectionColor; + background: $selectionBackgroundColor; + text-shadow: none; +} + +.reveal .slides section, +.reveal .slides section>section { + line-height: 1.3; + font-weight: inherit; +} + +/********************************************* + * HEADERS + *********************************************/ + +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: $headingMargin; + color: $headingColor; + + font-family: $headingFont; + font-weight: $headingFontWeight; + line-height: $headingLineHeight; + letter-spacing: $headingLetterSpacing; + + text-transform: $headingTextTransform; + text-shadow: $headingTextShadow; + + word-wrap: break-word; +} + +.reveal h1 {font-size: $heading1Size; } +.reveal h2 {font-size: $heading2Size; } +.reveal h3 {font-size: $heading3Size; } +.reveal h4 {font-size: $heading4Size; } + +.reveal h1 { + text-shadow: $heading1TextShadow; +} + + +/********************************************* + * OTHER + *********************************************/ + +.reveal p { + margin: $blockMargin 0; + line-height: 1.3; +} + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; +} +.reveal strong, +.reveal b { + font-weight: bold; +} + +.reveal em { + font-style: italic; +} + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + + text-align: left; + margin: 0 0 0 1em; +} + +.reveal ol { + list-style-type: decimal; +} + +.reveal ul { + list-style-type: disc; +} + +.reveal ul ul { + list-style-type: square; +} + +.reveal ul ul ul { + list-style-type: circle; +} + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; +} + +.reveal dt { + font-weight: bold; +} + +.reveal dd { + margin-left: 40px; +} + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: $blockMargin auto; + padding: 5px; + + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0,0,0,0.2); +} + .reveal blockquote p:first-child, + .reveal blockquote p:last-child { + display: inline-block; + } + +.reveal q { + font-style: italic; +} + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: $blockMargin auto; + + text-align: left; + font-size: 0.55em; + font-family: $codeFont; + line-height: 1.2em; + + word-wrap: break-word; + + box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); +} + +.reveal code { + font-family: $codeFont; + text-transform: none; +} + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; +} + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; +} + +.reveal table th { + font-weight: bold; +} + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; +} + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; +} + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; +} + +.reveal table tbody tr:last-child th, +.reveal table tbody tr:last-child td { + border-bottom: none; +} + +.reveal sup { + vertical-align: super; + font-size: smaller; +} +.reveal sub { + vertical-align: sub; + font-size: smaller; +} + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; +} + +.reveal small * { + vertical-align: top; +} + + +/********************************************* + * LINKS + *********************************************/ + +.reveal a { + color: $linkColor; + text-decoration: none; + + -webkit-transition: color .15s ease; + -moz-transition: color .15s ease; + transition: color .15s ease; +} + .reveal a:hover { + color: $linkColorHover; + + text-shadow: none; + border: none; + } + +.reveal .roll span:after { + color: #fff; + background: darken( $linkColor, 15% ); +} + + +/********************************************* + * IMAGES + *********************************************/ + +.reveal section img { + margin: 15px 0px; + background: rgba(255,255,255,0.12); + border: 4px solid $mainColor; + + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); +} + + .reveal section img.plain { + border: 0; + box-shadow: none; + } + + .reveal a img { + -webkit-transition: all .15s linear; + -moz-transition: all .15s linear; + transition: all .15s linear; + } + + .reveal a:hover img { + background: rgba(255,255,255,0.2); + border-color: $linkColor; + + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); + } + + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ + +.reveal .controls { + color: $linkColor; +} + + +/********************************************* + * PROGRESS BAR + *********************************************/ + +.reveal .progress { + background: rgba(0,0,0,0.2); + color: $linkColor; +} + .reveal .progress span { + -webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985); + -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985); + transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985); + } + +/********************************************* + * PRINT BACKGROUND + *********************************************/ + @media print { + .backgrounds { + background-color: $backgroundColor; + } +} diff --git a/talks/css/theme/white.css b/talks/css/theme/white.css new file mode 100755 index 000000000..43ef2c79e --- /dev/null +++ b/talks/css/theme/white.css @@ -0,0 +1,273 @@ +/** + * White theme for reveal.js. This is the opposite of the 'black' theme. + * + * By Hakim El Hattab, http://hakim.se + */ +@import url(../../lib/font/source-sans-pro/source-sans-pro.css); +section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 { + color: #fff; } + +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #fff; + background-color: #fff; } + +.reveal { + font-family: "Source Sans Pro", Helvetica, sans-serif; + font-size: 42px; + font-weight: normal; + color: #222; } + +::selection { + color: #fff; + background: #98bdef; + text-shadow: none; } + +::-moz-selection { + color: #fff; + background: #98bdef; + text-shadow: none; } + +.reveal .slides section, +.reveal .slides section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #222; + font-family: "Source Sans Pro", Helvetica, sans-serif; + font-weight: 600; + line-height: 1.2; + letter-spacing: normal; + text-transform: uppercase; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 2.5em; } + +.reveal h2 { + font-size: 1.6em; } + +.reveal h3 { + font-size: 1.3em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: none; } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); } + +.reveal code { + font-family: monospace; + text-transform: none; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tbody tr:last-child th, +.reveal table tbody tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; + font-size: smaller; } + +.reveal sub { + vertical-align: sub; + font-size: smaller; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #2a76dd; + text-decoration: none; + -webkit-transition: color .15s ease; + -moz-transition: color .15s ease; + transition: color .15s ease; } + +.reveal a:hover { + color: #6ca0e8; + text-shadow: none; + border: none; } + +.reveal .roll span:after { + color: #fff; + background: #1a53a1; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #222; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all .15s linear; + -moz-transition: all .15s linear; + transition: all .15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #2a76dd; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls { + color: #2a76dd; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); + color: #2a76dd; } + +.reveal .progress span { + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +/********************************************* + * PRINT BACKGROUND + *********************************************/ +@media print { + .backgrounds { + background-color: #fff; } } diff --git a/talks/cwi101.html b/talks/cwi101.html new file mode 100644 index 000000000..1807f12b3 --- /dev/null +++ b/talks/cwi101.html @@ -0,0 +1,351 @@ + + + + + + + + College of Western Idaho Information Literacy and Outreach Librarian Presentation for CWI 101 Classes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    +
    +

    CWI 101

    +

    CWI library staff won the Association of College and Research Library's 2019 Excellence in Academic Libraries award

    +

    To follow along, load this in your browser: https://www.ryanpatrickrandall.com/talks/cwi101.html

    +

    Created by Ryan P. Randall

    + +
    + +
    +

    Hello!

    +

    I'm Ryan Randall, from the library!

    +
    +

    Today's plan:

    +
      +
    • Build on the badges
    • +
    • Prep for your assignments
    • +
    • Focus on SIFT Moves
    • +
    + +
    +
    +
    +

    What have you already used with CWI Library?

    + +
      +
    • Badges?
    • +
    • Printing?
    • +
    • Textbook collection?
    • +
    • Computers or laptops?
    • +
    • Articles or books?
    • +
    • Online chat?
    • +
    • Anatomical models?
    • +
    +
    +
    +
    +

    Have your kids used the children's section?

    +

    Image of NCMP library's children's section with children's books

    +
    +
    +

    Did you come dressed up for Halloween?

    +
    +
    +
    +

    Read from our Popular Fiction sections?

    +

    Popular Fiction book shelves

    +
    +
    +

    Here's some more library resources!

    + +
    +
    +
    +
    +

    Source Evaluation & the SIFT Moves

    +
    +
    + +

    "Don't Hit Any Other Cars"

    + +
      +
    • Well-meaning advice isn't always useful. — What's a better way to help drivers learn how to drive?
    • +
    • Make the SIFT moves as natural as "look over your shoulder before you change lanes!"
    • + +
    + +
    +
    +

    SIFT Moves Help You Get Context, Fast!

    + +
    +
    +
    +
    +

    CRAAP test criteria

    +
      +
    • Currency
    • +
    • Relevance
    • +
    • Authority
    • +
    • Accuracy
    • +
    • Purpose
    • +
    +


    Blakeslee, S. (2004). The CRAAP test.

    + +
    +
    +

    Not a "Test"—It's Guidelines

    +

    Captain Barbossa saying 'The code is more what you call guidelines than actual rules'

    +
      +
    • The CRAAP criteria help you decide where to place your trust. They're not a simple litmus test.
    • +
    +
    +
    +

    Currency

    +

    man hanging from clocktower clock face

    +
      +
    • When was this source published?
    • +
    • The timeframe of some information is crucial.
    • +
    +

    +

    +
    +
    +

    Relevance

    +

    multiple 'why?'s written on chalkboard

    +
      +
    • Why is this right for this assignment?
    • +
    • Are its approach and depth suitable for your purposes?
    • +
    + +
    +
    +

    Authority

    +

    Carmen Sandiego

    +
      +
    • Who wrote this?
    • +
    • Do they have appropriate expertise on this subject?
    • +
    + +
    +
    +

    Accuracy

    +

    Merida shooting a bullseye with an arrow

    +
      +
    • How does this source support its claims?
    • +
    • Can you check where the authors got their facts & examples?
    • +
    + +
    +
    +

    Purpose

    +

    File label that says 'purpose'

    +
      +
    • Why was this written?
    • +
    • Is the author trying to benefit personally from this?
    • +
    + +
    +
    +

    CRAAP test criteria

    +
      +
    • Currency
    • +
    • Relevance
    • +
    • Authority
    • +
    • Accuracy
    • +
    • Purpose
    • +
    +


    Blakeslee, S. (2004). The CRAAP test.

    + +
    +
    +
    +
    +

    Map Your Research Process

    +

    BB8 droid projecting a map

    +

    Take two minutes to write an overview of how and where you research things.

    +
    +
    +

    What did your overview include?

    +
    +
    +

    Research as a circular puzzle. The stages are: define task, identify options, select sources, analyze content, and present findings. Evaluate is an interior piece linking all the outside circular pieces.

    +
    +
    +

    Research process as a hiking map

    +
    +
    + +
    +
    +

    What's this about "Fake News?"

    + +
    +
    +

    Facebook Echo Chambers

    + +
    +
    +

    Fake News Examples

    + +
    +
    +

    Let's Break "Fake News" Down

    +
      +
    • misinformation
    • unintentionally false +
    • disinformation
    • intentionally false +
    • propaganda
    • false and usually emotionally manipulative +
    +
    + +
    +

    How to Spot Fake News

    +

    This handout could help!

    +
    +
    +

    Why Does Fake News Exist?

    +

    This LA Times article suggests it's most often about money.

    +
    +
    +

    What are the consequences of fake news?

    +

    Well, at Comet Pizza, "Fake News Brought Real Guns"

    +
    +
    +

    For more…

    +

    We could talk a lot more about this!

    +

    UW even has a whole class about reasoning in a digital world. Check it out if you care about this stuff.

    +
    +
    + +
    +

    How did this go? Let me know at https://bit.ly/cwilif!

    +
    + + +
    +

    Keep in touch with the CWI Library

    +
    +

    Please schedule an appointment with a CWI Librarian if you'd like further research assistance.

    +

    You can also get help from the College of Western Idaho Libraries through our online chat, our FAQ pages, calling or texting us, and email!

    +
    +

    Thank you for your time!
    +

    +

    Sources

    + "Pulling a book off the shelf" photo by Bennington College's Crossett Library with a CC BY-NC-SA 2.0 license.
    + Blakeslee, S. (2004). The CRAAP test. LOEX Quarterly, 31(3), 6-7. Retrieved from https://commons.emich.edu/loexquarterly/vol31/iss3/4.
    + "Purpose" photo by Seth Sawyers with a CC BY 2.0 license and given some minimal filtering by Ryan.

    + "Reflect • Learn • Connect" photo by Seattle Community Colleges with a CC BY-NC-SA 3.0 license. +
    + + +
    + +
    + + + + + + + + diff --git a/talks/cyoat.html b/talks/cyoat.html new file mode 100644 index 000000000..07d5195d6 --- /dev/null +++ b/talks/cyoat.html @@ -0,0 +1,186 @@ + + + + + + + + Choose Your Own Adventure Time + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    +
    +

    Choose Your Own Adventure Time

    +
    +
    +

    Ryan Randall

    +
    +

    2021-10-15

    +
    +
    Jake listening to headphones and nodding
    +
    +

    If you'd like to follow along, browse to: https://www.ryanpatrickrandall.com/talks/cyoat.html +

    + +
    +
    +

    My Goals for This CYOA Test

    +
      +
    • Try out Reveal
    • +
    • …and its abilities for instruction
    • +
    • Have some nerdy fun
    • +
    + +
    +
    +

    A Choice!

    +

    Do you want to:

    + +
    +
    +

    No Spoilers!

    + River Song saying spoilers to the Doctor +

    I'm pretty sure you didn't want to ruin the surprise. How about you go back and click on a choice?

    +
    +
    +
    +

    Option A

    +

    Here's some text.

    +

    Scroll down for another choice.

    +
    +
    +

    Option A1

    +

    Do you choose to:

    + +
    +
    +
    +

    Option B

    +

    Here's some other text.

    +

    Swipe right to see what happens!

    +
    +
    +

    Evaluation

    +
    +
    +

    Upsides

    +
      +
    • It's all open source
    • +
    • Can control layout & visuals
    • +
    • Screen reader accessible (if using reveal-a11y plugin)
    • +
    +
    +
    +

    Downsides

    +
      +
    • Author in html, optionally also markdown
    • +
    • Adding layouts isn't simple
    • +
    • Choices & progress are on "the honor system"
    • +
    +
    +
    +
    +
    +

    We All Win!

    +

    jake from Adventure Time with the word SUPER
    Choose Yr Own Adventure Test Time +

    +
    + +
    + +
    + + + + + + + + + \ No newline at end of file diff --git a/talks/demo.html b/talks/demo.html new file mode 100755 index 000000000..f88bfa269 --- /dev/null +++ b/talks/demo.html @@ -0,0 +1,425 @@ + + + + + + + reveal.js – The HTML Presentation Framework + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    +
    +

    Reveal.js

    +

    The HTML Presentation Framework

    +

    + Created by Hakim El Hattab and contributors +

    +
    + +
    +

    Hello There

    +

    + reveal.js enables you to create beautiful interactive slide decks using HTML. This presentation will show you examples of what it can do. +

    +
    + + +
    +
    +

    Vertical Slides

    +

    Slides can be nested inside of each other.

    +

    Use the Space key to navigate through all slides.

    +
    + + Down arrow + +
    +
    +

    Basement Level 1

    +

    Nested slides are useful for adding additional detail underneath a high level horizontal slide.

    +
    +
    +

    Basement Level 2

    +

    That's it, time to go back up.

    +
    + + Up arrow + +
    +
    + +
    +

    Slides

    +

    + Not a coder? Not a problem. There's a fully-featured visual editor for authoring these, try it out at https://slides.com. +

    +
    + +
    +

    Point of View

    +

    + Press ESC to enter the slide overview. +

    +

    + Hold down the alt key (ctrl in Linux) and click on any element to zoom towards it using zoom.js. Click again to zoom back out. +

    +

    + (NOTE: Use ctrl + click in Linux.) +

    +
    + +
    +

    Touch Optimized

    +

    + Presentations look great on touch devices, like mobile phones and tablets. Simply swipe through your slides. +

    +
    + +
    + +
    + +
    +
    +

    Fragments

    +

    Hit the next arrow...

    +

    ... to step through ...

    +

    ... a fragmented slide.

    + + +
    +
    +

    Fragment Styles

    +

    There's different types of fragments, like:

    +

    grow

    +

    shrink

    +

    fade-out

    +

    + fade-right, + up, + down, + left +

    +

    fade-in-then-out

    +

    fade-in-then-semi-out

    +

    Highlight red blue green

    +
    +
    + +
    +

    Transition Styles

    +

    + You can select from different transitions, like:
    + None - + Fade - + Slide - + Convex - + Concave - + Zoom +

    +
    + +
    +

    Themes

    +

    + reveal.js comes with a few themes built in:
    + + Black (default) - + White - + League - + Sky - + Beige - + Simple
    + Serif - + Blood - + Night - + Moon - + Solarized +

    +
    + +
    +
    +

    Slide Backgrounds

    +

    + Set data-background="#dddddd" on a slide to change the background color. All CSS color formats are supported. +

    + + Down arrow + +
    +
    +

    Image Backgrounds

    +
    <section data-background="image.png">
    +
    +
    +

    Tiled Backgrounds

    +
    <section data-background="image.png" data-background-repeat="repeat" data-background-size="100px">
    +
    +
    +
    +

    Video Backgrounds

    +
    <section data-background-video="video.mp4,video.webm">
    +
    +
    +
    +

    ... and GIFs!

    +
    +
    + +
    +

    Background Transitions

    +

    + Different background transitions are available via the backgroundTransition option. This one's called "zoom". +

    +
    Reveal.configure({ backgroundTransition: 'zoom' })
    +
    + +
    +

    Background Transitions

    +

    + You can override background transitions per-slide. +

    +
    <section data-background-transition="zoom">
    +
    + +
    +
    +

    Iframe Backgrounds

    +

    Since reveal.js runs on the web, you can easily embed other web content. Try interacting with the page in the background.

    +
    +
    + +
    +

    Pretty Code

    +
    
    +import React, { useState } from 'react';
    +
    +function Example() {
    +  const [count, setCount] = useState(0);
    +
    +  return (
    +    <div>
    +      <p>You clicked {count} times</p>
    +      <button onClick={() => setCount(count + 1)}>
    +        Click me
    +      </button>
    +    </div>
    +  );
    +}
    +					
    +

    Code syntax highlighting courtesy of highlight.js.

    +
    + +
    +

    Marvelous List

    +
      +
    • No order here
    • +
    • Or here
    • +
    • Or here
    • +
    • Or here
    • +
    +
    + +
    +

    Fantastic Ordered List

    +
      +
    1. One is smaller than...
    2. +
    3. Two is smaller than...
    4. +
    5. Three!
    6. +
    +
    + +
    +

    Tabular Tables

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    ItemValueQuantity
    Apples$17
    Lemonade$218
    Bread$32
    +
    + +
    +

    Clever Quotes

    +

    + These guys come in two forms, inline: The nice thing about standards is that there are so many to choose from and block: +

    +
    + “For years there has been a theory that millions of monkeys typing at random on millions of typewriters would + reproduce the entire works of Shakespeare. The Internet has proven this theory to be untrue.” +
    +
    + +
    +

    Intergalactic Interconnections

    +

    + You can link between slides internally, + like this. +

    +
    + +
    +

    Speaker View

    +

    There's a speaker view. It includes a timer, preview of the upcoming slide as well as your speaker notes.

    +

    Press the S key to try it out.

    + + +
    + +
    +

    Export to PDF

    +

    Presentations can be exported to PDF, here's an example:

    + +
    + +
    +

    Global State

    +

    + Set data-state="something" on a slide and "something" + will be added as a class to the document element when the slide is open. This lets you + apply broader style changes, like switching the page background. +

    +
    + +
    +

    State Events

    +

    + Additionally custom events can be triggered on a per slide basis by binding to the data-state name. +

    +
    
    +Reveal.addEventListener( 'customevent', function() {
    +	console.log( '"customevent" has fired' );
    +} );
    +					
    +
    + +
    +

    Take a Moment

    +

    + Press B or . on your keyboard to pause the presentation. This is helpful when you're on stage and want to take distracting slides off the screen. +

    +
    + +
    +

    Much more

    + +
    + +
    +

    THE END

    +

    + - Try the online editor
    + - Source code & documentation +

    +
    + +
    + +
    + + + + + + + diff --git a/talks/dh+lib-draft.html b/talks/dh+lib-draft.html new file mode 100644 index 000000000..16c1d38c8 --- /dev/null +++ b/talks/dh+lib-draft.html @@ -0,0 +1,64 @@ + + + + + + dh+lib draft + + + + + + + + + +

    DH at the Desk

    + +

    It’s still reference—We’re just adding more tools

    + +

    Most librarians likely view reference on a spectrum between providing transparent service and point-of-need instruction. You might regard the goal of reference as efficient delivery of information to patrons. On the other end, you might consider our roles more as guides who tacitly instruct or outright collaborate with patrons to improve their searching skills and sophistication with knowledge structures and research processes. Wherever you reside on this continuum, digital humanities tools can help accomplish your goals. This post will show you what two different text mining tools can do for you and your patrons at the reference desk.[1]

    + +

    Text mining tools often are the best candidates for use at the reference desk, considering the constraints of time and attention that frequently accompany these interactions. Two of the handiest are Google Ngram Viewer, which counts frequencies of words in various corpora from their Google Books collection, and Voyant-Tools, which can do similar analyses for user-supplied texts. As web-based tools that do not charge for access, they’re close to ubiquitously available, and they require little specialized knowledge other than gaining familiarity with their interfaces.

    + +

    Add It Up

    + +

    What can counting terms help show at the reference desk? If a patron wants help deciding on words or phrases to use for their search, turning to Ngrams can help show the likely frequency and age of results for each term. A patron wanting to research non-heterosexual identities might benefit from seeing how some related terms have been used over time:

    + +

    + +

    While few college-age patrons would likely be surprised that terms like “queer” and “gay” have shifted meaning over time, it can be useful to demonstrate just how commonly they were once used compared to now. Word counts are, of course, neither “conclusions” or “solutions” to research, but rather can lead to a more advanced understanding of terminology and why one might need to search for multiple terms to perform an adequate inquiry for their purposes. An excellent feature of Google’s Ngrams Viewer is that individual results can be clicked on and read within their context in the original document. The graph also provides a useful layer of abstraction that can help give novice or impatient researchers time to see why they might want to consider searching with multiple terms. The interface can also help more visual learners actually see the dramatic shift in usage, perhaps assisting them to understand it more fully.

    + +

    Introspection

    + +

    In addition to looking for broad trends across many texts, patrons can also benefit from tools that help examine a single work. Counting the frequency of terms might help a patron consider aspects of a work to research further, or what keywords to use for secondary literature. Although this use isn’t exclusive to academic libraries, it might be most easily explained with a student example.

    + +

    A student who appears taken aback by how dramatically Mary Shelley’s Frankenstein differs from the Hollywood/Halloween folk imaginary could benefit from being shown Voyant, for this tool could help the student think through what the novel’s word choice emphasizes.

    + +

    + +

    Above is an embedded view of Voyant already loaded with a copy of Shelley’s Frankenstein from GITenburg, a repository of texts from Project Gutenberg that seeks to make the files even more user-friendly.[2] As we can see in the “Summary” tool in the lower left, the five most frequent words in this text are man, life, father, shall, and eyes. If I were trying to help a student develop a search strategy based on terms, I’d likely ask them to describe the type of horror these words provoke. Do these terms sound more akin to existential horror or a creature feature? What other words might the student want to consider exploring as possible themes or ideas that run through the work?

    + +

    Using text analysis tools at the reference desk additionally helps scaffold more sophisticated understandings of data and searching. Once they start looking at the words that are most frequently used in a text and begin trying to link them to their own reading or experience of that work, a student might rightfully protest that not all the concepts in the work show up with the same term throughout: “Sometimes Shelley might be using synonyms! She might be varying her word choice for effect or nuance! Counting the terms doesn’t account for this!”
    +Isn’t this the sort of critical engagement with research that we long to help develop through our reference encounters? By giving patrons an environment to do text analysis within a work-slash-data-set that they already have encountered in its entirety, a tool like Voyant positions them in a place more conducive to active, thoughtful criticism than relying on intermediaries like the reference desk librarian’s toolbox of Library of Congress Search Headings and related strategies.

    + +

    Whether you lean more toward seeing reference as a service or, with James K. Elmborg, allow space for “Teaching at the Desk”, consider adding text analysis tools like Google Ngrams and Voyant to your repertoire.

    + +
    +
    +
      + +
    1. +

      Indeed, a number of librarians and DH practitioners have discussed how well they complement each other. A great starting point for this is Andrea Baer’s “Critical Information Literacy in the College Classroom: Exploring Scholarly Knowledge Production through the Digital Humanities”.  ↩

      +
    2. + +
    3. +

      Specifically, I’ve also told the various tools—each of which has its own settings in its smaller frame inside the window—to ignore the most common words in English. You can do this yourself by clicking on the gear icon (“Options”), then selecting and applying one of the “stop words” lists. There is a check box that allows you to use the stop word list for just that single tool or for all of the tools in the Voyant window. GITenburg seeks to build on Project Gutenberg by making the various texts even more accessible to other tools and to make submitting revisions easier by using the GIT version control software on GitHub.  ↩

      +
    4. + +
    +
    + + + + diff --git a/talks/engl101.html b/talks/engl101.html new file mode 100644 index 000000000..9f1d69d36 --- /dev/null +++ b/talks/engl101.html @@ -0,0 +1,198 @@ + + + + + + + + College of Western Idaho Information Literacy and Outreach Librarian Presentation for English 101 Classes + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    +
    +

    English 101

    +

    +

    CWI library staff won the Association of College and Research Library's 2019 Excellence in Academic Libraries award

    +

    To follow along, load this in your browser: https://www.ryanpatrickrandall.com/talks/engl101.html

    +

    Created by Ryan P. Randall

    + +
    + +
    +

    Hello!

    +

    I'm Ryan Randall, from the Library!

    +
    +
    +

    I'm here to help you prepare for your next assignment. And the rest of your classes, to be honest.

    +

    Today we'll talk mostly about thesis statements and finding & using sources.

    + +
    +
    +
    +

    What have you already done in the library?

    + +
      +
    • Printing?
    • +
    • Used the textbooks on reserve?
    • +
    • Used one of our many computers?
    • +
    • Requested an article or book?
    • +
    • Used the online chat?
    • +
    • Used the anatomical models?
    • +
    +
    +
    +
    +

    Have your kids used the children's section?

    +

    Image of NCMP library's children's section with children's books

    +
    +
    +

    Did you come dressed up for Halloween?

    +
    +
    +
    +

    Read from our Popular Fiction sections?

    +

    Popular Fiction book shelves

    +
    +
    +

    Here's some more library resources!

    + +
    +
    +
    +
    +

    Peer review? Databases?

    +
    +
    +

    Peer reviewed ≅ refereed

    +
  • What's all this about peer review? Isn't that just having other students look at my essays?
  • +
  • Not exactly! Let's watch a video from NCSU on peer review.
  • +
    +
    +

    Here's how an idea goes from a researcher to journal to a database.

    +
    +
    + +
    +
    +

    Thesis Statements

    +
      +
    • Statement of fact: Hybrid cars are more energy efficient than cars with standard gasoline engines.
    • +
    • Thesis statement: Although hybrid cars could decrease our country's dependence on foreign oil, they have disadvantages.
    • +
    +
    +
    +
    +
    +

    BEAM analysis

    +
      +
    • Background: general information
    • +
    • Exhibit (aka Evidence): examples or evidence to analyze
    • +
    • Argument: engaging, amplifying, or refuting a source's assertions
    • +
    • Method (aka Model): borrowing an approach
    • +
    +
    +
    +
    +

    How did this go? Let me know at https://bit.ly/cwilif!

    +
    + + +
    +

    Keep in touch with the CWI Library

    +
    +

    Please schedule an appointment with a CWI Librarian if you'd like further research assistance.

    +

    You can also get help from the College of Western Idaho Libraries through our online chat, our FAQ pages, calling or texting us, and email!

    +
    +

    Thank you for your time!
    + "Pulling a book off the shelf" photo by Bennington College's Crossett Library with a CC BY-NC-SA 2.0 license.
    + Blakeslee, S. (2004). The CRAAP test. LOEX Quarterly, 31(3), 6-7. Retrieved from https://commons.emich.edu/loexquarterly/vol31/iss3/4.
    + "Purpose" photo by Seth Sawyers with a CC BY 2.0 license and given some minimal filtering by Ryan.

    +
    + + +
    +
    + +
    +
    + + + + + + + + \ No newline at end of file diff --git a/talks/engl102.html b/talks/engl102.html new file mode 100644 index 000000000..a628225f8 --- /dev/null +++ b/talks/engl102.html @@ -0,0 +1,254 @@ + + + + + + + + College of Western Idaho Information Literacy and Outreach Librarian Presentation for English 102 Classes + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    +
    +

    English 102

    +

    CWI library staff won the Association of College and Research Library's 2019 Excellence in Academic Libraries award

    +

    To follow along, load this in your browser: https://www.ryanpatrickrandall.com/talks/engl102.html

    +

    Created by Ryan P. Randall

    +
    + +
    +

    Hello!

    +

    I'm Ryan Randall, from the Library!

    +
    +

    I'm here to help you prepare for your next assignment. And the rest of your classes, to be honest.

    +

    We'll talk about the inquiry process and advanced searching.

    +
    +
    +
    +

    What have you already done in the library?

    + +
      +
    • Printing?
    • +
    • Used the textbooks on reserve?
    • +
    • Used one of our many computers?
    • +
    • Requested an article or book?
    • +
    • Used the online chat?
    • +
    • Used the anatomical models?
    • +
    +
    +
    +
    +

    Here's some more library resources!

    + +
    +
    +

    Any questions so far?

    +

    Person's hand turning pages of a book, with every having only a single large question mark

    +
    +
    +
    +
    +

    The Inquiry Process

    +

    "Research" is not finding a hidden cave full of facts.

    +

    So what is it?

    +
    +
    +

    For one, it's a process!

    +

    Let's take three minutes to talk about how you currently research things. What do you do? How do you start? How do you end?

    +
    +
    +

    So, what do you do?

    +

    Where do you tend to look?

    +

    How do you decide if it's good to use?

    +

    When do you know it's time to stop?

    +

    Wait: how did you even know what question you were asking?

    +
    +
    +

    Research Process

    +

    1: Project Assigned. 2: Pick your topic. 3: Circle of stages: a. Focus your topic. b. Find sources. c. Read and evaluate sources. 4: Write/create and edit. 5: Project due.

    +

    It might surprise you, but expert writers go through that middle circle repeatedly.

    +
    +
    +

    Inquiry Process (An Expanded Research Process)

    +

    1: Pose real questions. 2: Find resources. 3: Interpret information. 4: Report findings.

    +

    Ask yourself questions in each part to help you move along!

    +
    +
    +

    Research as a circular puzzle. The stages are: define task, identify options, select sources, analyze content, and present findings. Evaluate is an interior piece linking all the outside circular pieces.

    +

    The Seattle Community Colleges's research process puzzle shows evaluation as central.

    +
    +
    +
    +
    +

    Abstraction ⇒ Action

    +

    aka "I'm happy for you & I'm gonna let you finish
    but I need to get this paper done"

    +
    +
    +

    Another Version of the Inquiry Process

    +
      + +
    1. Essential Question: What do you want to know?
    2. +
    3. Proposal & Plan: How & where will you search?
    4. +
    5. Explore & Research: How does what you find change your approach? How can experts help?
    6. +
    7. Put It All Together: Make an appointment with CWI's Writing Center!
    8. +
    9. Share It All: Turn in what you've made!
    10. +
    +
    +
    +

    The Library can help most with the first three parts.

    +

    Here's some great places to start!

    + +
    +
    +
    +
    +

    Article Searching +

    +

    Close-up on man's face with advanced math symbols.

    +
    +
    +

    Keywords and Advanced Search are Your Friends

    +

    Let's work on developing the keywords for your search.

    +
    +
    +

    Search Term Brainstorming

    + + + + + + + + + + + + + + + + + + + +
     TopicBroaderNarrowerSynonymRelated
    examples:carvehicleHondaautomobiletruck
    +
    +
    +
    +
    +

    Book Searching +

    +

    Cat looking around while wearing glasses

    +
    +
    +

    Let's try searching for books related to our topic.

    +
    +
    + +
    +

    How did this go? Let me know at https://bit.ly/cwilif!

    +
    + + +
    +

    Keep in touch with the CWI Library

    +
    +

    Please schedule an appointment with a CWI Librarian if you'd like further research assistance.

    +

    You can also get help from the College of Western Idaho Libraries through our online chat, our FAQ pages, calling or texting us, and email!

    +
    +

    Thank you for your time!
    + "Pulling a book off the shelf" photo by Bennington College's Crossett Library with a CC BY-NC-SA 2.0 license.
    + Blakeslee, S. (2004). The CRAAP test. LOEX Quarterly, 31(3), 6-7. Retrieved from https://commons.emich.edu/loexquarterly/vol31/iss3/4.
    + "Purpose" photo by Seth Sawyers with a CC BY 2.0 license and given some minimal filtering by Ryan.

    +
    + + +
    +
    + +
    +
    + + + + + + + + \ No newline at end of file diff --git a/talks/engl5581.html b/talks/engl5581.html new file mode 100644 index 000000000..f4fab19e6 --- /dev/null +++ b/talks/engl5581.html @@ -0,0 +1,139 @@ + + + + + + + + ENGL 5581 Phrasal Verbs + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    +
    +

    Grammar Minute

    +

    Phrasal Verbs

    +

    To follow along, load this in your browser: https://www.ryanpatrickrandall.com/talks/engl5581.html

    +
    +
    +

    What's a phrasal verb?

    +

    It's a verb that requires multiple words for its meaning.

    +
    +
    +

    Can you give me an example?

    +
      +
    • blew up
    • +
    • Example: The volcano blew up.
    • +
    • took on
    • +
    • Example: The ambitious sophmore took on too many advanced classes that semester.
    • +
    +
    +
    +

    "She looked it up on her computer."

    +

    woman lying down on her back, reaching up and typing on a laptop held by a stand

    +
    +
    +

    "She looked it up on her computer."

    +

    Duck Duck Go search engine

    +
    +
    +

    Strategies?

    +

    In small groups, take two minutes to brainstorm strategies that help you evaluate if a verb is a phrasal verb.

    +

    What makes sense to you?

    +
    +
    +

    Transitive verbs

    +
      +
    • Can you move the verb particle around?
    • +
    • Example: The student looked up the assignment in Moodle.
    • +
    • Example: The student looked the assignment up in Moodle.
    • +
    • took on
    • +
    • Example: The ambitious sophmore took on too many advanced classes that semester.
    • +
    +
    +
    +

    Intransitive verbs

    +
      +
    • Can you use a synonym?
    • +
    • Example: The volcano blew up.
    • +
    • Example: The volcano exploded.
    • +
    +
    +
    +

    Thank You!

    +

    +

    +
    +
    + +
    +
    + + + + + + + + diff --git a/talks/engl6612.html b/talks/engl6612.html new file mode 100644 index 000000000..e4b0eba4b --- /dev/null +++ b/talks/engl6612.html @@ -0,0 +1,116 @@ + + + + + + + + ENGL 6612 Williams + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    +
    +

    Raymond Williams

    +

    Dominant, Residual, and Emergent (1977)

    +

    +

    To follow along, load this in your browser: https://www.ryanpatrickrandall.com/talks/engl6612.html

    +

    + Created by Ryan P. Randall +

    + +
    +
    +
    +
      +
    • Welsh academic, critic, and novelist
    • +
    • Undergrad and MA from Trinity College, Cambridge
    • +
    • Tutor in adult education at Oxford
    • +
    • Professor at Cambridge and later at Stanford
    • +
    +
    +
    +

    +

    Cover of _Keywords_

    +
    +
    +
    +

    Our Article

    +
      +
    • Dominant
    • +
    • Residual
    • +
    • Emergent
    • +
    + +
    + +
    + +
    + + + + + + + + diff --git a/talks/hacklibraryschool.html b/talks/hacklibraryschool.html new file mode 100644 index 000000000..96e440423 --- /dev/null +++ b/talks/hacklibraryschool.html @@ -0,0 +1,130 @@ + + + + + + + Hack Library School + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    +
    +

    Reveal.Js

    +

    It's More Interactive!

    +
    +

    I loved it. It was much better than Cats. I'm going to use it again and again.

    +
    +

    + Created for Hack Library School +

    + +
    +
    +

    Features

    +

    Reveal.Js has arrow button navigation & fragments:

    +
      +
    1. "Fragments" mean that things will appear sequentially.
    2. +
    3. This will appear after the first.
    4. +
    5. …and finally, this will as well!
    6. +
    + +
    +
    +

    Another slide!

    +
    +
    +

    Go look at the project's webpage for all the gritty details!

    + +
    + + +
    +
    +

    Reveal.js Navigation can also go vertically!

    +

    This helps when you want to show a few facets of a subject.

    +
    +

    image of downward pointing arrow

    +
    +
    +

    Reveal.js is Awesomesauce!

    + GIF image of Jake from the *Adventure Time* cartoon series looking very excited +

    I think you'll agree that this is concentrated radness.

    +

    Thank you for your time!
    + Arrow icon by Mister Pixel from The Noun Project Creative Commons Attribution (CC-BY 3.0)

    +
    +
    + +
    + +
    + + + + + + + + diff --git a/talks/igc2019.html b/talks/igc2019.html new file mode 100644 index 000000000..b2a9f71cd --- /dev/null +++ b/talks/igc2019.html @@ -0,0 +1,113 @@ + + + + + + + + Intermountain Graduate Conference Paper + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    +
    +

    Is a Plant a Document?

    +

    The Knowledge Practices of Renaissance Natural History, Francis Bacon, and Contemporary Library Science

    +

    Ryan P. Randall

    +

    To follow along, load this in your browser: https://www.ryanpatrickrandall.com/talks/igc2019.html

    +
    +
    +

    rough woodcut with few details

    +
    +
    +

    line drawing with more details

    +
    +
    +

    line drawing with more details

    +
    +
    +

    line drawing with more details

    +
    +
    +

    line drawing with more details

    +
    +
    +

    line drawing with more details

    +
    + + + +
    +
    + +
    +
    + + + + + + + + diff --git a/talks/images/APINPopFic.jpg b/talks/images/APINPopFic.jpg new file mode 100644 index 000000000..153cdfab4 Binary files /dev/null and b/talks/images/APINPopFic.jpg differ diff --git a/talks/images/CWI-library-logo.jpg b/talks/images/CWI-library-logo.jpg new file mode 100644 index 000000000..5b9b65c5c Binary files /dev/null and b/talks/images/CWI-library-logo.jpg differ diff --git a/talks/images/CWI_location.jpg b/talks/images/CWI_location.jpg new file mode 100644 index 000000000..fc7c262bc Binary files /dev/null and b/talks/images/CWI_location.jpg differ diff --git a/talks/images/Capal2016-01.png b/talks/images/Capal2016-01.png new file mode 100644 index 000000000..dbf538a51 Binary files /dev/null and b/talks/images/Capal2016-01.png differ diff --git a/talks/images/Capal2016-02.png b/talks/images/Capal2016-02.png new file mode 100644 index 000000000..39ad2b8c4 Binary files /dev/null and b/talks/images/Capal2016-02.png differ diff --git a/talks/images/Capal2016-03.png b/talks/images/Capal2016-03.png new file mode 100644 index 000000000..15d043fc9 Binary files /dev/null and b/talks/images/Capal2016-03.png differ diff --git a/talks/images/Capal2016-04.png b/talks/images/Capal2016-04.png new file mode 100644 index 000000000..a7fbd7c69 Binary files /dev/null and b/talks/images/Capal2016-04.png differ diff --git a/talks/images/Capal2016-05.png b/talks/images/Capal2016-05.png new file mode 100644 index 000000000..e88a0feed Binary files /dev/null and b/talks/images/Capal2016-05.png differ diff --git a/talks/images/Capal2016-06.png b/talks/images/Capal2016-06.png new file mode 100644 index 000000000..156062ae3 Binary files /dev/null and b/talks/images/Capal2016-06.png differ diff --git a/talks/images/Capal2016-07.png b/talks/images/Capal2016-07.png new file mode 100644 index 000000000..c24ffb1e1 Binary files /dev/null and b/talks/images/Capal2016-07.png differ diff --git a/talks/images/Capal2016-08.png b/talks/images/Capal2016-08.png new file mode 100644 index 000000000..82f09ae40 Binary files /dev/null and b/talks/images/Capal2016-08.png differ diff --git a/talks/images/Capal2016-09.png b/talks/images/Capal2016-09.png new file mode 100644 index 000000000..93bfa7501 Binary files /dev/null and b/talks/images/Capal2016-09.png differ diff --git a/talks/images/Capal2016-10.png b/talks/images/Capal2016-10.png new file mode 100644 index 000000000..3ee9c791d Binary files /dev/null and b/talks/images/Capal2016-10.png differ diff --git a/talks/images/Capal2016-11.png b/talks/images/Capal2016-11.png new file mode 100644 index 000000000..72d984376 Binary files /dev/null and b/talks/images/Capal2016-11.png differ diff --git a/talks/images/Capal2016-12.png b/talks/images/Capal2016-12.png new file mode 100644 index 000000000..6838cd33a Binary files /dev/null and b/talks/images/Capal2016-12.png differ diff --git a/talks/images/Capal2016-13.png b/talks/images/Capal2016-13.png new file mode 100644 index 000000000..77a2cf1fa Binary files /dev/null and b/talks/images/Capal2016-13.png differ diff --git a/talks/images/Capal2016-14.png b/talks/images/Capal2016-14.png new file mode 100644 index 000000000..05335555d Binary files /dev/null and b/talks/images/Capal2016-14.png differ diff --git a/talks/images/NCMPHalloween2015.jpg b/talks/images/NCMPHalloween2015.jpg new file mode 100644 index 000000000..1c0e34471 Binary files /dev/null and b/talks/images/NCMPHalloween2015.jpg differ diff --git a/talks/images/NCMPchildrensection.jpg b/talks/images/NCMPchildrensection.jpg new file mode 100644 index 000000000..949599ec1 Binary files /dev/null and b/talks/images/NCMPchildrensection.jpg differ diff --git a/talks/images/accuracy.gif b/talks/images/accuracy.gif new file mode 100644 index 000000000..38617f455 Binary files /dev/null and b/talks/images/accuracy.gif differ diff --git a/talks/images/acrl2021_paper_pdf.png b/talks/images/acrl2021_paper_pdf.png new file mode 100644 index 000000000..01342dda0 Binary files /dev/null and b/talks/images/acrl2021_paper_pdf.png differ diff --git a/talks/images/adventure-time-jake-headphones.gif b/talks/images/adventure-time-jake-headphones.gif new file mode 100644 index 000000000..c8a540526 Binary files /dev/null and b/talks/images/adventure-time-jake-headphones.gif differ diff --git a/talks/images/adventure-time-jake-super-rainbow-bg.gif b/talks/images/adventure-time-jake-super-rainbow-bg.gif new file mode 100644 index 000000000..eb1121165 Binary files /dev/null and b/talks/images/adventure-time-jake-super-rainbow-bg.gif differ diff --git a/talks/images/at_hug.gif b/talks/images/at_hug.gif new file mode 100644 index 000000000..97af843d3 Binary files /dev/null and b/talks/images/at_hug.gif differ diff --git a/talks/images/authority.gif b/talks/images/authority.gif new file mode 100644 index 000000000..fd84fd2bd Binary files /dev/null and b/talks/images/authority.gif differ diff --git a/talks/images/backpackUnpacked.jpg b/talks/images/backpackUnpacked.jpg new file mode 100644 index 000000000..d5281ad1d Binary files /dev/null and b/talks/images/backpackUnpacked.jpg differ diff --git a/talks/images/barbossaGuidelines.gif b/talks/images/barbossaGuidelines.gif new file mode 100644 index 000000000..7216a5943 Binary files /dev/null and b/talks/images/barbossaGuidelines.gif differ diff --git a/talks/images/blueFeedRedFeed.png b/talks/images/blueFeedRedFeed.png new file mode 100644 index 000000000..aad2d2002 Binary files /dev/null and b/talks/images/blueFeedRedFeed.png differ diff --git a/talks/images/brunfels.png b/talks/images/brunfels.png new file mode 100644 index 000000000..7a058d643 Binary files /dev/null and b/talks/images/brunfels.png differ diff --git a/talks/images/capitol_crawl.jpg b/talks/images/capitol_crawl.jpg new file mode 100644 index 000000000..d52d3d015 Binary files /dev/null and b/talks/images/capitol_crawl.jpg differ diff --git a/talks/images/cat-glasses.gif b/talks/images/cat-glasses.gif new file mode 100644 index 000000000..2c3b2dee4 Binary files /dev/null and b/talks/images/cat-glasses.gif differ diff --git a/talks/images/clock-lloyd.gif b/talks/images/clock-lloyd.gif new file mode 100644 index 000000000..f5dcf509c Binary files /dev/null and b/talks/images/clock-lloyd.gif differ diff --git a/talks/images/communitas.jpg b/talks/images/communitas.jpg new file mode 100644 index 000000000..cc7588af2 Binary files /dev/null and b/talks/images/communitas.jpg differ diff --git a/talks/images/craapAccuracyMerida.jpg b/talks/images/craapAccuracyMerida.jpg new file mode 100644 index 000000000..fc4c6d5c1 Binary files /dev/null and b/talks/images/craapAccuracyMerida.jpg differ diff --git a/talks/images/crossettlibrary.jpg b/talks/images/crossettlibrary.jpg new file mode 100644 index 000000000..b22928da6 Binary files /dev/null and b/talks/images/crossettlibrary.jpg differ diff --git a/talks/images/cwi-award.png b/talks/images/cwi-award.png new file mode 100644 index 000000000..442d07951 Binary files /dev/null and b/talks/images/cwi-award.png differ diff --git a/talks/images/cwi-logo.jpg b/talks/images/cwi-logo.jpg new file mode 100644 index 000000000..a5786185c Binary files /dev/null and b/talks/images/cwi-logo.jpg differ diff --git a/talks/images/cwiLibrariesAreForEveryoneButtons.jpg b/talks/images/cwiLibrariesAreForEveryoneButtons.jpg new file mode 100644 index 000000000..ae717820e Binary files /dev/null and b/talks/images/cwiLibrariesAreForEveryoneButtons.jpg differ diff --git a/talks/images/cwiResearchBasicsBadgeSet.png b/talks/images/cwiResearchBasicsBadgeSet.png new file mode 100644 index 000000000..1a5defe4c Binary files /dev/null and b/talks/images/cwiResearchBasicsBadgeSet.png differ diff --git a/talks/images/dataSam.png b/talks/images/dataSam.png new file mode 100644 index 000000000..7f6cb69ce Binary files /dev/null and b/talks/images/dataSam.png differ diff --git a/talks/images/doctor-who-spoilers.gif b/talks/images/doctor-who-spoilers.gif new file mode 100644 index 000000000..105eff01b Binary files /dev/null and b/talks/images/doctor-who-spoilers.gif differ diff --git a/talks/images/downarrow.png b/talks/images/downarrow.png new file mode 100644 index 000000000..1934ab400 Binary files /dev/null and b/talks/images/downarrow.png differ diff --git a/talks/images/fakeFukushimaFlowers.png b/talks/images/fakeFukushimaFlowers.png new file mode 100644 index 000000000..9fbac8873 Binary files /dev/null and b/talks/images/fakeFukushimaFlowers.png differ diff --git a/talks/images/fakeNewsIFLA.png b/talks/images/fakeNewsIFLA.png new file mode 100644 index 000000000..a4b509b6a Binary files /dev/null and b/talks/images/fakeNewsIFLA.png differ diff --git a/talks/images/fakeObamaBan.png b/talks/images/fakeObamaBan.png new file mode 100644 index 000000000..da5daf286 Binary files /dev/null and b/talks/images/fakeObamaBan.png differ diff --git a/talks/images/fakePizzaGateConsequences.png b/talks/images/fakePizzaGateConsequences.png new file mode 100644 index 000000000..ede3d5850 Binary files /dev/null and b/talks/images/fakePizzaGateConsequences.png differ diff --git a/talks/images/fakeSpectrum.png b/talks/images/fakeSpectrum.png new file mode 100644 index 000000000..1dcf8d097 Binary files /dev/null and b/talks/images/fakeSpectrum.png differ diff --git a/talks/images/fakeWritersLB.png b/talks/images/fakeWritersLB.png new file mode 100644 index 000000000..0c218ad87 Binary files /dev/null and b/talks/images/fakeWritersLB.png differ diff --git a/talks/images/gallery.png b/talks/images/gallery.png new file mode 100644 index 000000000..eab2bf97e Binary files /dev/null and b/talks/images/gallery.png differ diff --git a/talks/images/gnb.png b/talks/images/gnb.png new file mode 100644 index 000000000..ce5bed870 Binary files /dev/null and b/talks/images/gnb.png differ diff --git a/talks/images/gormanOEVR.jpg b/talks/images/gormanOEVR.jpg new file mode 100644 index 000000000..6c0d6f917 Binary files /dev/null and b/talks/images/gormanOEVR.jpg differ diff --git a/talks/images/hooks02.jpg b/talks/images/hooks02.jpg new file mode 100644 index 000000000..c4d941943 Binary files /dev/null and b/talks/images/hooks02.jpg differ diff --git a/talks/images/horizon.png b/talks/images/horizon.png new file mode 100644 index 000000000..ed398f85f Binary files /dev/null and b/talks/images/horizon.png differ diff --git a/talks/images/hurricane-katrina-satellite.gif b/talks/images/hurricane-katrina-satellite.gif new file mode 100644 index 000000000..40a796489 Binary files /dev/null and b/talks/images/hurricane-katrina-satellite.gif differ diff --git a/talks/images/iisc_equalityEquity.png b/talks/images/iisc_equalityEquity.png new file mode 100644 index 000000000..4d2fec7e3 Binary files /dev/null and b/talks/images/iisc_equalityEquity.png differ diff --git a/talks/images/inquiry-compass.jpg b/talks/images/inquiry-compass.jpg new file mode 100644 index 000000000..69f8da7eb Binary files /dev/null and b/talks/images/inquiry-compass.jpg differ diff --git a/talks/images/inquiry-process-columns.jpeg b/talks/images/inquiry-process-columns.jpeg new file mode 100644 index 000000000..9d18ccd24 Binary files /dev/null and b/talks/images/inquiry-process-columns.jpeg differ diff --git a/talks/images/inquiryHiking.jpg b/talks/images/inquiryHiking.jpg new file mode 100644 index 000000000..6b0a85d97 Binary files /dev/null and b/talks/images/inquiryHiking.jpg differ diff --git a/talks/images/inquiryProcessHiking.png b/talks/images/inquiryProcessHiking.png new file mode 100644 index 000000000..851551a90 Binary files /dev/null and b/talks/images/inquiryProcessHiking.png differ diff --git a/talks/images/iris-rlc-model-working.gif b/talks/images/iris-rlc-model-working.gif new file mode 100644 index 000000000..f40148b00 Binary files /dev/null and b/talks/images/iris-rlc-model-working.gif differ diff --git a/talks/images/iublogo.png b/talks/images/iublogo.png new file mode 100644 index 000000000..e6d464632 Binary files /dev/null and b/talks/images/iublogo.png differ diff --git a/talks/images/keywords.jpg b/talks/images/keywords.jpg new file mode 100644 index 000000000..00ebe15d2 Binary files /dev/null and b/talks/images/keywords.jpg differ diff --git a/talks/images/lg_biabh.jpg b/talks/images/lg_biabh.jpg new file mode 100644 index 000000000..2740986fa Binary files /dev/null and b/talks/images/lg_biabh.jpg differ diff --git a/talks/images/lying-down-laptop-stand.jpg b/talks/images/lying-down-laptop-stand.jpg new file mode 100644 index 000000000..8e3dd25cc Binary files /dev/null and b/talks/images/lying-down-laptop-stand.jpg differ diff --git a/talks/images/mapBB8.gif b/talks/images/mapBB8.gif new file mode 100644 index 000000000..c783a33cc Binary files /dev/null and b/talks/images/mapBB8.gif differ diff --git a/talks/images/markdownexample.png b/talks/images/markdownexample.png new file mode 100644 index 000000000..6fbbdb303 Binary files /dev/null and b/talks/images/markdownexample.png differ diff --git a/talks/images/math.gif b/talks/images/math.gif new file mode 100644 index 000000000..3037a3162 Binary files /dev/null and b/talks/images/math.gif differ diff --git a/talks/images/mess.jpg b/talks/images/mess.jpg new file mode 100644 index 000000000..42e8730fc Binary files /dev/null and b/talks/images/mess.jpg differ diff --git a/talks/images/metadata.jpg b/talks/images/metadata.jpg new file mode 100644 index 000000000..fd8b5c3c5 Binary files /dev/null and b/talks/images/metadata.jpg differ diff --git a/talks/images/ncmpBookDrop.jpg b/talks/images/ncmpBookDrop.jpg new file mode 100644 index 000000000..c648c830c Binary files /dev/null and b/talks/images/ncmpBookDrop.jpg differ diff --git a/talks/images/penguinDraculaCover.jpeg b/talks/images/penguinDraculaCover.jpeg new file mode 100644 index 000000000..e8d6044a2 Binary files /dev/null and b/talks/images/penguinDraculaCover.jpeg differ diff --git a/talks/images/potato.png b/talks/images/potato.png new file mode 100644 index 000000000..8432d2573 Binary files /dev/null and b/talks/images/potato.png differ diff --git a/talks/images/pressed.jpeg b/talks/images/pressed.jpeg new file mode 100644 index 000000000..f314f9ca7 Binary files /dev/null and b/talks/images/pressed.jpeg differ diff --git a/talks/images/purposephotohls.jpg b/talks/images/purposephotohls.jpg new file mode 100644 index 000000000..4d8e8adb1 Binary files /dev/null and b/talks/images/purposephotohls.jpg differ diff --git a/talks/images/question-book.gif b/talks/images/question-book.gif new file mode 100644 index 000000000..c1c213545 Binary files /dev/null and b/talks/images/question-book.gif differ diff --git a/talks/images/radway_reading.jpg b/talks/images/radway_reading.jpg new file mode 100644 index 000000000..ae8a02033 Binary files /dev/null and b/talks/images/radway_reading.jpg differ diff --git a/talks/images/refugeesWelcomeID.jpg b/talks/images/refugeesWelcomeID.jpg new file mode 100644 index 000000000..42298a3d2 Binary files /dev/null and b/talks/images/refugeesWelcomeID.jpg differ diff --git a/talks/images/refugeesWelcomeW.jpg b/talks/images/refugeesWelcomeW.jpg new file mode 100644 index 000000000..ed4865e94 Binary files /dev/null and b/talks/images/refugeesWelcomeW.jpg differ diff --git a/talks/images/relevance.gif b/talks/images/relevance.gif new file mode 100644 index 000000000..c9bf1bbfd Binary files /dev/null and b/talks/images/relevance.gif differ diff --git a/talks/images/research-process-line-2019.png b/talks/images/research-process-line-2019.png new file mode 100644 index 000000000..db71105a0 Binary files /dev/null and b/talks/images/research-process-line-2019.png differ diff --git a/talks/images/rightarrow.png b/talks/images/rightarrow.png new file mode 100644 index 000000000..70e9b9c04 Binary files /dev/null and b/talks/images/rightarrow.png differ diff --git a/talks/images/ryanTram600x600.jpeg b/talks/images/ryanTram600x600.jpeg new file mode 100644 index 000000000..6ceed18e6 Binary files /dev/null and b/talks/images/ryanTram600x600.jpeg differ diff --git a/talks/images/search-ddg.png b/talks/images/search-ddg.png new file mode 100644 index 000000000..578c1a0a7 Binary files /dev/null and b/talks/images/search-ddg.png differ diff --git a/talks/images/ss_Accessible_Equivalents.png b/talks/images/ss_Accessible_Equivalents.png new file mode 100644 index 000000000..60202e7f5 Binary files /dev/null and b/talks/images/ss_Accessible_Equivalents.png differ diff --git a/talks/images/ss_Google_Slides.png b/talks/images/ss_Google_Slides.png new file mode 100644 index 000000000..10b79a265 Binary files /dev/null and b/talks/images/ss_Google_Slides.png differ diff --git a/talks/images/ss_Information_Timeline.png b/talks/images/ss_Information_Timeline.png new file mode 100644 index 000000000..8b3c13693 Binary files /dev/null and b/talks/images/ss_Information_Timeline.png differ diff --git a/talks/images/ss_SIFT_quiz.png b/talks/images/ss_SIFT_quiz.png new file mode 100644 index 000000000..01cbcca87 Binary files /dev/null and b/talks/images/ss_SIFT_quiz.png differ diff --git a/talks/images/ss_SIFT_video.png b/talks/images/ss_SIFT_video.png new file mode 100644 index 000000000..44ecce53b Binary files /dev/null and b/talks/images/ss_SIFT_video.png differ diff --git a/talks/images/ss_overview.png b/talks/images/ss_overview.png new file mode 100644 index 000000000..92ca06be0 Binary files /dev/null and b/talks/images/ss_overview.png differ diff --git a/talks/images/stanfordCredibilityStudy.png b/talks/images/stanfordCredibilityStudy.png new file mode 100644 index 000000000..c09c6b047 Binary files /dev/null and b/talks/images/stanfordCredibilityStudy.png differ diff --git a/talks/images/storify.jpg b/talks/images/storify.jpg new file mode 100644 index 000000000..747f56442 Binary files /dev/null and b/talks/images/storify.jpg differ diff --git a/talks/images/williams_desk.jpg b/talks/images/williams_desk.jpg new file mode 100644 index 000000000..85f36854d Binary files /dev/null and b/talks/images/williams_desk.jpg differ diff --git a/talks/images/woodcut.png b/talks/images/woodcut.png new file mode 100644 index 000000000..94746e041 Binary files /dev/null and b/talks/images/woodcut.png differ diff --git a/talks/index.html b/talks/index.html new file mode 100755 index 000000000..f938be548 --- /dev/null +++ b/talks/index.html @@ -0,0 +1,49 @@ + + + + + + + reveal.js + + + + + + + + + + + + +
    +
    +
    Slide 1
    +
    Slide 2
    +
    +
    + + + + + + diff --git a/talks/indexY.html b/talks/indexY.html new file mode 100644 index 000000000..40e849f37 --- /dev/null +++ b/talks/indexY.html @@ -0,0 +1,412 @@ + + + + + + + reveal.js - The HTML Presentation Framework + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    +
    +

    Reveal.js

    +

    The HTML Presentation Framework

    +

    + Created by Hakim El Hattab / @hakimel +

    +
    + +
    +

    Hello There

    +

    + reveal.js enables you to create beautiful interactive slide decks using HTML. This presentation will show you examples of what it can do. +

    +
    + + +
    +
    +

    Vertical Slides

    +

    Slides can be nested inside of each other.

    +

    Use the Space key to navigate through all slides.

    +
    + + Down arrow + +
    +
    +

    Basement Level 1

    +

    Nested slides are useful for adding additional detail underneath a high level horizontal slide.

    +
    +
    +

    Basement Level 2

    +

    That's it, time to go back up.

    +
    + + Up arrow + +
    +
    + +
    +

    Slides

    +

    + Not a coder? Not a problem. There's a fully-featured visual editor for authoring these, try it out at http://slides.com. +

    +
    + +
    +

    Point of View

    +

    + Press ESC to enter the slide overview. +

    +

    + Hold down alt and click on any element to zoom in on it using zoom.js. Alt + click anywhere to zoom back out. +

    +
    + +
    +

    Touch Optimized

    +

    + Presentations look great on touch devices, like mobile phones and tablets. Simply swipe through your slides. +

    +
    + +
    + +
    + +
    +
    +

    Fragments

    +

    Hit the next arrow...

    +

    ... to step through ...

    +

    ... a fragmented slide.

    + + +
    +
    +

    Fragment Styles

    +

    There's different types of fragments, like:

    +

    grow

    +

    shrink

    +

    roll-in

    +

    fade-out

    +

    current-visible

    +

    highlight-red

    +

    highlight-blue

    +
    +
    + +
    +

    Transition Styles

    +

    + You can select from different transitions, like:
    + None - + Fade - + Slide - + Convex - + Concave - + Zoom +

    +
    + +
    +

    Themes

    +

    + reveal.js comes with a few themes built in:
    + + Black (default) - + White - + League - + Sky - + Beige - + Simple
    + Serif - + Night - + Moon - + Solarized +

    +
    + +
    +
    +

    Slide Backgrounds

    +

    + Set data-background="#dddddd" on a slide to change the background color. All CSS color formats are supported. +

    + + Down arrow + +
    +
    +

    Image Backgrounds

    +
    <section data-background="image.png">
    +
    +
    +

    Tiled Backgrounds

    +
    <section data-background="image.png" data-background-repeat="repeat" data-background-size="100px">
    +
    +
    +
    +

    Video Backgrounds

    +
    <section data-background-video="video.mp4,video.webm">
    +
    +
    +
    + +
    +

    Background Transitions

    +

    + Different background transitions are available via the backgroundTransition option. This one's called "zoom". +

    +
    Reveal.configure({ backgroundTransition: 'zoom' })
    +
    + +
    +

    Background Transitions

    +

    + You can override background transitions per-slide. +

    +
    <section data-background-transition="zoom">
    +
    + +
    +

    Pretty Code

    +
    
    +function linkify( selector ) {
    +  if( supports3DTransforms ) {
    +
    +    var nodes = document.querySelectorAll( selector );
    +
    +    for( var i = 0, len = nodes.length; i < len; i++ ) {
    +      var node = nodes[i];
    +
    +      if( !node.className ) {
    +        node.className += ' roll';
    +      }
    +    }
    +  }
    +}
    +					
    +

    Code syntax highlighting courtesy of highlight.js.

    +
    + +
    +

    Marvelous List

    +
      +
    • No order here
    • +
    • Or here
    • +
    • Or here
    • +
    • Or here
    • +
    +
    + +
    +

    Fantastic Ordered List

    +
      +
    1. One is smaller than...
    2. +
    3. Two is smaller than...
    4. +
    5. Three!
    6. +
    +
    + +
    +

    Tabular Tables

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    ItemValueQuantity
    Apples$17
    Lemonade$218
    Bread$32
    +
    + +
    +

    Clever Quotes

    +

    + These guys come in two forms, inline: + “The nice thing about standards is that there are so many to choose from” and block: +

    +
    + “For years there has been a theory that millions of monkeys typing at random on millions of typewriters would + reproduce the entire works of Shakespeare. The Internet has proven this theory to be untrue.” +
    +
    + +
    +

    Intergalactic Interconnections

    +

    + You can link between slides internally, + like this. +

    +
    + +
    +

    Speaker View

    +

    There's a speaker view. It includes a timer, preview of the upcoming slide as well as your speaker notes.

    +

    Press the S key to try it out.

    + + +
    + +
    +

    Export to PDF

    +

    Presentations can be exported to PDF, here's an example:

    + +
    + +
    +

    Global State

    +

    + Set data-state="something" on a slide and "something" + will be added as a class to the document element when the slide is open. This lets you + apply broader style changes, like switching the page background. +

    +
    + +
    +

    State Events

    +

    + Additionally custom events can be triggered on a per slide basis by binding to the data-state name. +

    +
    
    +Reveal.addEventListener( 'customevent', function() {
    +	console.log( '"customevent" has fired' );
    +} );
    +					
    +
    + +
    +

    Take a Moment

    +

    + Press B or . on your keyboard to pause the presentation. This is helpful when you're on stage and want to take distracting slides off the screen. +

    +
    + +
    +

    Much more

    + +
    + +
    +

    THE END

    +

    + - Try the online editor
    + - Source code & documentation +

    +
    + +
    + +
    + + + + + + + + diff --git a/talks/itrc.html b/talks/itrc.html new file mode 100644 index 000000000..5cbbb9a20 --- /dev/null +++ b/talks/itrc.html @@ -0,0 +1,401 @@ + + + + + + + + + + Presentation for ISU's Instructional Designer Position at the ITRC + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    +
    +

    Instructional Designer

    +
    +
    +

    Ryan Randall

    +
    +

    2022-03-25

    +
    +
    Ryan smiling in a friendly close-up
    +
    +

    If you'd like to follow along, please browse to:
    https://www.ryanpatrickrandall.com/talks/itrc.html
    +

    + +
    +
    +

    My Goals for This Presentation

    +
      +
    • Briefly share my background
    • +
    • Present recommendations for improvements to
      HO 0107: Medical Law and Ethics
    • +
    • 20 minutes for this presentation,
      then 10 minutes for Q & A
    • +
    + +
    +
    + +
    +

    Hello!

    +

    CWI's Instruction Coordinator & Faculty Outreach Librarian

    +

    CWI library staff won the Association of College and Research Library's 2019 Excellence in Academic Libraries award +

    + +
    +
    +

    At CWI

    +
    +
    +

    CWI Library's instruction room, with slide about evaluating source accuracy, illustrated with a gif of Merida shooting an arrow
    Inside the Library:
    Instruction Coordinator +

    +
    +
    +

    CWI's Nampa Campus Multipurpose Building, with library bookdrop in foreground
    Outside the Library:
    Faculty Outreach +

    +
    +
    + +
    +
    +

    Before CWI…

    +
    +

    First-Year Composition & Other Courses
    +

    Writing Centers
    +

    User & Space Studies
    +
    + +
    + + +
    +
    +
    +

    Course Background Information

    +

    HO 0107 - 02: Medical Law and Ethics

    +


    Prerequisite for several ISU degrees

    + +
    +
    +

    Student Perspective

    +
      +
    1. Students love the textbook and find it an easy read
    2. +
    3. Student engagement is a struggle
    4. +
    + +
    +
    +

    Faculty Concerns

    +
      +
    1. Faculty would like to improve instructor presence
    2. +
    3. Faculty would like to improve accessibility
    4. +
    5. Faculty would like explore implementing Universal Design for Learning (UDL)
    6. +
    + +
    +
    +
    +
    +

    Recommendations

    +

    Current Strengths

    +
      +
    1. Introductions, both yours and the students
    2. +
    3. Student-to-student forum
    4. +
    5. Videos with captions
    6. +
    +
    +
    +
    +
    +

    Recommendation One

    +

    Consider using more frequent, short videos

    +
      +
    • Your own video introduction
    • +
    • Invite students to post video introductions as well
    • +
    +
    +
    +

    Recommendation One: Videos

    +

    Vanderbuilt's educational video review suggests
    videos be no longer than 6-9 minutes

    +

    UDL guidelines suggest multiple modes for
    engaging with content and communicating student understanding

    +
    +
    +

    Recommendation One: Videos

    +

    Informal, shorter videos can address:
    +

      +
    • instructor presence
    • +
    • accessibility
    • +
    • student engagement
    • +

    +
    +
    +
    +
    +

    Recommendation Two

    +

    Consider optional student video or multimedia responses on forum Assignments

    +

    Media exclusively? media as supplements to written elements? Your choice!

    +
    +

    CAST has useful, short pages on using audio, images, and videos accessibly

    +
    +
    +

    Recommendation Two: Multimedia Options

    +

    These could address:
    +

      +
    • UDL recommendation for multiple means of communication
    • +
    • Student feelings of community belonging and engagement
    • +
    +

    +
    +
    +

    Recommendation Two: Multimedia Options

    +
      +
    • Caution: consider demonstrating how students can add captions and alt text to their media, particularly if you offer this option for forum posts
    • +
    • Benefit: multimedia creation and accessibility are valuable, transferable skills
    • +
    +
    +
    +
    +
    +

    Recommendation Three

    +

    Consider a Student-Faculty Forum, similar to your existing Student-Student Forum

    +
    +
    +

    Recommendation Three

    +

    UDL encourages adaptive design, and the Universal Design for Learning: A Practical Guide* encourages student feedback as part of "design thinking"

    +
    +

    * written by Takacs and Zhang of the Justice Institute of British Columbia, therefore not one of CAST's official UDL resources… but very useful!

    +
    +
    +

    Recommendation Three: Student-Faculty Forum

    +

    Formative student feedback could help:

    + +
      +
    • your efforts find the lowest-hanging fruit
    • +
    • student engagement with material and classmates
    • +
    • you learn why students love the textbook, to better draw upon what they love
    • +
    • inform future iterations of the course
    • +
    +
    +
    +
    +
    +
    +

    Recommendation Four

    +

    Consider Clarifying and Minimizing Potential Sources of Confusion

    +

    This could address:

    +
      +
    • faculty interest in accessibility and UDL
    • +
    • help students better engage with material
    • +
    +
    +
    +

    Recommendation Four: Clarify

    +

    Consider adding your own synthesis or highlights to materials

    +
    +

    Referring to course performance and learning objectives is a strength!

    +

    Reducing the executive function necessary for students to make these connections takes this strength further

    +
    +
    +

    Recommendation Four: Clarify

    +

    UDL has excellent examples for clarifying

    +

    For example, you could list assignments in more strictly chronological sequence

    + +
    +
    +

    Recommendation Four: Clarify

    +

    Consider Using Inline Frames for Documents

    + +

    Moodle's documentation has more details on using IFrames in Moodle.

    +
    +
    +
    +
    +

    Recommendation Five

    +

    Additional "What Will You Learn" Summaries

    +

    These can help students:

    +
      +
    • better understand in the short term
    • +
    • better prepare for transfer in the long term
    • +
    +
    +
    +

    Recommendation Five: Summaries

    +

    You've already begun doing this!

    +
    +

    Consider doing it more intentionally and consistently

    +
    +
    +
    +
    +

    Recommendations Summary

    +
      +
    1. Use multimedia
    2. +
    3. Optional media responses
    4. +
    5. Student-Faculty forum
    6. +
    7. Clarify for engagement & executive function
    8. +
    9. "What Will You Learn?" summaries
    10. +
    +
    +
    +
    +

    Revisiting Our Goals

    +
      +
    • Share my background
    • +
    • Share my recommendations
    • +
      +
    • Now, please share your questions!
    • +
    + +
    + +
    + + + + + + + + + \ No newline at end of file diff --git a/talks/js/reveal.js b/talks/js/reveal.js new file mode 100755 index 000000000..5c026db71 --- /dev/null +++ b/talks/js/reveal.js @@ -0,0 +1,6028 @@ +/*! + * reveal.js + * http://revealjs.com + * MIT licensed + * + * Copyright (C) 2019 Hakim El Hattab, http://hakim.se + */ +(function( root, factory ) { + if( typeof define === 'function' && define.amd ) { + // AMD. Register as an anonymous module. + define( function() { + root.Reveal = factory(); + return root.Reveal; + } ); + } else if( typeof exports === 'object' ) { + // Node. Does not work with strict CommonJS. + module.exports = factory(); + } else { + // Browser globals. + root.Reveal = factory(); + } +}( this, function() { + + 'use strict'; + + var Reveal; + + // The reveal.js version + var VERSION = '3.8.0'; + + var SLIDES_SELECTOR = '.slides section', + HORIZONTAL_SLIDES_SELECTOR = '.slides>section', + VERTICAL_SLIDES_SELECTOR = '.slides>section.present>section', + HOME_SLIDE_SELECTOR = '.slides>section:first-of-type', + UA = navigator.userAgent, + + // Configuration defaults, can be overridden at initialization time + config = { + + // The "normal" size of the presentation, aspect ratio will be preserved + // when the presentation is scaled to fit different resolutions + width: 960, + height: 700, + + // Factor of the display size that should remain empty around the content + margin: 0.04, + + // Bounds for smallest/largest possible scale to apply to content + minScale: 0.2, + maxScale: 2.0, + + // Display presentation control arrows + controls: true, + + // Help the user learn the controls by providing hints, for example by + // bouncing the down arrow when they first encounter a vertical slide + controlsTutorial: true, + + // Determines where controls appear, "edges" or "bottom-right" + controlsLayout: 'bottom-right', + + // Visibility rule for backwards navigation arrows; "faded", "hidden" + // or "visible" + controlsBackArrows: 'faded', + + // Display a presentation progress bar + progress: true, + + // Display the page number of the current slide + // - true: Show slide number + // - false: Hide slide number + // + // Can optionally be set as a string that specifies the number formatting: + // - "h.v": Horizontal . vertical slide number (default) + // - "h/v": Horizontal / vertical slide number + // - "c": Flattened slide number + // - "c/t": Flattened slide number / total slides + // + // Alternatively, you can provide a function that returns the slide + // number for the current slide. The function needs to return an array + // with one string [slideNumber] or three strings [n1,delimiter,n2]. + // See #formatSlideNumber(). + slideNumber: false, + + // Can be used to limit the contexts in which the slide number appears + // - "all": Always show the slide number + // - "print": Only when printing to PDF + // - "speaker": Only in the speaker view + showSlideNumber: 'all', + + // Use 1 based indexing for # links to match slide number (default is zero + // based) + hashOneBasedIndex: false, + + // Add the current slide number to the URL hash so that reloading the + // page/copying the URL will return you to the same slide + hash: false, + + // Push each slide change to the browser history. Implies `hash: true` + history: false, + + // Enable keyboard shortcuts for navigation + keyboard: true, + + // Optional function that blocks keyboard events when retuning false + keyboardCondition: null, + + // Enable the slide overview mode + overview: true, + + // Disables the default reveal.js slide layout so that you can use + // custom CSS layout + disableLayout: false, + + // Vertical centering of slides + center: true, + + // Enables touch navigation on devices with touch input + touch: true, + + // Loop the presentation + loop: false, + + // Change the presentation direction to be RTL + rtl: false, + + // Changes the behavior of our navigation directions. + // + // "default" + // Left/right arrow keys step between horizontal slides, up/down + // arrow keys step between vertical slides. Space key steps through + // all slides (both horizontal and vertical). + // + // "linear" + // Removes the up/down arrows. Left/right arrows step through all + // slides (both horizontal and vertical). + // + // "grid" + // When this is enabled, stepping left/right from a vertical stack + // to an adjacent vertical stack will land you at the same vertical + // index. + // + // Consider a deck with six slides ordered in two vertical stacks: + // 1.1 2.1 + // 1.2 2.2 + // 1.3 2.3 + // + // If you're on slide 1.3 and navigate right, you will normally move + // from 1.3 -> 2.1. If "grid" is used, the same navigation takes you + // from 1.3 -> 2.3. + navigationMode: 'default', + + // Randomizes the order of slides each time the presentation loads + shuffle: false, + + // Turns fragments on and off globally + fragments: true, + + // Flags whether to include the current fragment in the URL, + // so that reloading brings you to the same fragment position + fragmentInURL: false, + + // Flags if the presentation is running in an embedded mode, + // i.e. contained within a limited portion of the screen + embedded: false, + + // Flags if we should show a help overlay when the question-mark + // key is pressed + help: true, + + // Flags if it should be possible to pause the presentation (blackout) + pause: true, + + // Flags if speaker notes should be visible to all viewers + showNotes: false, + + // Global override for autolaying embedded media (video/audio/iframe) + // - null: Media will only autoplay if data-autoplay is present + // - true: All media will autoplay, regardless of individual setting + // - false: No media will autoplay, regardless of individual setting + autoPlayMedia: null, + + // Global override for preloading lazy-loaded iframes + // - null: Iframes with data-src AND data-preload will be loaded when within + // the viewDistance, iframes with only data-src will be loaded when visible + // - true: All iframes with data-src will be loaded when within the viewDistance + // - false: All iframes with data-src will be loaded only when visible + preloadIframes: null, + + // Controls automatic progression to the next slide + // - 0: Auto-sliding only happens if the data-autoslide HTML attribute + // is present on the current slide or fragment + // - 1+: All slides will progress automatically at the given interval + // - false: No auto-sliding, even if data-autoslide is present + autoSlide: 0, + + // Stop auto-sliding after user input + autoSlideStoppable: true, + + // Use this method for navigation when auto-sliding (defaults to navigateNext) + autoSlideMethod: null, + + // Specify the average time in seconds that you think you will spend + // presenting each slide. This is used to show a pacing timer in the + // speaker view + defaultTiming: null, + + // Enable slide navigation via mouse wheel + mouseWheel: false, + + // Apply a 3D roll to links on hover + rollingLinks: false, + + // Hides the address bar on mobile devices + hideAddressBar: true, + + // Opens links in an iframe preview overlay + // Add `data-preview-link` and `data-preview-link="false"` to customise each link + // individually + previewLinks: false, + + // Exposes the reveal.js API through window.postMessage + postMessage: true, + + // Dispatches all reveal.js events to the parent window through postMessage + postMessageEvents: false, + + // Focuses body when page changes visibility to ensure keyboard shortcuts work + focusBodyOnPageVisibilityChange: true, + + // Transition style + transition: 'slide', // none/fade/slide/convex/concave/zoom + + // Transition speed + transitionSpeed: 'default', // default/fast/slow + + // Transition style for full page slide backgrounds + backgroundTransition: 'fade', // none/fade/slide/convex/concave/zoom + + // Parallax background image + parallaxBackgroundImage: '', // CSS syntax, e.g. "a.jpg" + + // Parallax background size + parallaxBackgroundSize: '', // CSS syntax, e.g. "3000px 2000px" + + // Parallax background repeat + parallaxBackgroundRepeat: '', // repeat/repeat-x/repeat-y/no-repeat/initial/inherit + + // Parallax background position + parallaxBackgroundPosition: '', // CSS syntax, e.g. "top left" + + // Amount of pixels to move the parallax background per slide step + parallaxBackgroundHorizontal: null, + parallaxBackgroundVertical: null, + + // The maximum number of pages a single slide can expand onto when printing + // to PDF, unlimited by default + pdfMaxPagesPerSlide: Number.POSITIVE_INFINITY, + + // Prints each fragment on a separate slide + pdfSeparateFragments: true, + + // Offset used to reduce the height of content within exported PDF pages. + // This exists to account for environment differences based on how you + // print to PDF. CLI printing options, like phantomjs and wkpdf, can end + // on precisely the total height of the document whereas in-browser + // printing has to end one pixel before. + pdfPageHeightOffset: -1, + + // Number of slides away from the current that are visible + viewDistance: 3, + + // The display mode that will be used to show slides + display: 'block', + + // Hide cursor if inactive + hideInactiveCursor: true, + + // Time before the cursor is hidden (in ms) + hideCursorTime: 5000, + + // Script dependencies to load + dependencies: [] + + }, + + // Flags if Reveal.initialize() has been called + initialized = false, + + // Flags if reveal.js is loaded (has dispatched the 'ready' event) + loaded = false, + + // Flags if the overview mode is currently active + overview = false, + + // Holds the dimensions of our overview slides, including margins + overviewSlideWidth = null, + overviewSlideHeight = null, + + // The horizontal and vertical index of the currently active slide + indexh, + indexv, + + // The previous and current slide HTML elements + previousSlide, + currentSlide, + + previousBackground, + + // Remember which directions that the user has navigated towards + hasNavigatedRight = false, + hasNavigatedDown = false, + + // Slides may hold a data-state attribute which we pick up and apply + // as a class to the body. This list contains the combined state of + // all current slides. + state = [], + + // The current scale of the presentation (see width/height config) + scale = 1, + + // CSS transform that is currently applied to the slides container, + // split into two groups + slidesTransform = { layout: '', overview: '' }, + + // Cached references to DOM elements + dom = {}, + + // A list of registered reveal.js plugins + plugins = {}, + + // List of asynchronously loaded reveal.js dependencies + asyncDependencies = [], + + // Features supported by the browser, see #checkCapabilities() + features = {}, + + // Client is a mobile device, see #checkCapabilities() + isMobileDevice, + + // Client is a desktop Chrome, see #checkCapabilities() + isChrome, + + // Throttles mouse wheel navigation + lastMouseWheelStep = 0, + + // Delays updates to the URL due to a Chrome thumbnailer bug + writeURLTimeout = 0, + + // Is the mouse pointer currently hidden from view + cursorHidden = false, + + // Timeout used to determine when the cursor is inactive + cursorInactiveTimeout = 0, + + // Flags if the interaction event listeners are bound + eventsAreBound = false, + + // The current auto-slide duration + autoSlide = 0, + + // Auto slide properties + autoSlidePlayer, + autoSlideTimeout = 0, + autoSlideStartTime = -1, + autoSlidePaused = false, + + // Holds information about the currently ongoing touch input + touch = { + startX: 0, + startY: 0, + startCount: 0, + captured: false, + threshold: 40 + }, + + // A key:value map of shortcut keyboard keys and descriptions of + // the actions they trigger, generated in #configure() + keyboardShortcuts = {}, + + // Holds custom key code mappings + registeredKeyBindings = {}; + + /** + * Starts up the presentation if the client is capable. + */ + function initialize( options ) { + + // Make sure we only initialize once + if( initialized === true ) return; + + initialized = true; + + checkCapabilities(); + + if( !features.transforms2d && !features.transforms3d ) { + document.body.setAttribute( 'class', 'no-transforms' ); + + // Since JS won't be running any further, we load all lazy + // loading elements upfront + var images = toArray( document.getElementsByTagName( 'img' ) ), + iframes = toArray( document.getElementsByTagName( 'iframe' ) ); + + var lazyLoadable = images.concat( iframes ); + + for( var i = 0, len = lazyLoadable.length; i < len; i++ ) { + var element = lazyLoadable[i]; + if( element.getAttribute( 'data-src' ) ) { + element.setAttribute( 'src', element.getAttribute( 'data-src' ) ); + element.removeAttribute( 'data-src' ); + } + } + + // If the browser doesn't support core features we won't be + // using JavaScript to control the presentation + return; + } + + // Cache references to key DOM elements + dom.wrapper = document.querySelector( '.reveal' ); + dom.slides = document.querySelector( '.reveal .slides' ); + + // Force a layout when the whole page, incl fonts, has loaded + window.addEventListener( 'load', layout, false ); + + var query = Reveal.getQueryHash(); + + // Do not accept new dependencies via query config to avoid + // the potential of malicious script injection + if( typeof query['dependencies'] !== 'undefined' ) delete query['dependencies']; + + // Copy options over to our config object + extend( config, options ); + extend( config, query ); + + // Hide the address bar in mobile browsers + hideAddressBar(); + + // Loads dependencies and continues to #start() once done + load(); + + } + + /** + * Inspect the client to see what it's capable of, this + * should only happens once per runtime. + */ + function checkCapabilities() { + + isMobileDevice = /(iphone|ipod|ipad|android)/gi.test( UA ); + isChrome = /chrome/i.test( UA ) && !/edge/i.test( UA ); + + var testElement = document.createElement( 'div' ); + + features.transforms3d = 'WebkitPerspective' in testElement.style || + 'MozPerspective' in testElement.style || + 'msPerspective' in testElement.style || + 'OPerspective' in testElement.style || + 'perspective' in testElement.style; + + features.transforms2d = 'WebkitTransform' in testElement.style || + 'MozTransform' in testElement.style || + 'msTransform' in testElement.style || + 'OTransform' in testElement.style || + 'transform' in testElement.style; + + features.requestAnimationFrameMethod = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame; + features.requestAnimationFrame = typeof features.requestAnimationFrameMethod === 'function'; + + features.canvas = !!document.createElement( 'canvas' ).getContext; + + // Transitions in the overview are disabled in desktop and + // Safari due to lag + features.overviewTransitions = !/Version\/[\d\.]+.*Safari/.test( UA ); + + // Flags if we should use zoom instead of transform to scale + // up slides. Zoom produces crisper results but has a lot of + // xbrowser quirks so we only use it in whitelsited browsers. + features.zoom = 'zoom' in testElement.style && !isMobileDevice && + ( isChrome || /Version\/[\d\.]+.*Safari/.test( UA ) ); + + } + + /** + * Loads the dependencies of reveal.js. Dependencies are + * defined via the configuration option 'dependencies' + * and will be loaded prior to starting/binding reveal.js. + * Some dependencies may have an 'async' flag, if so they + * will load after reveal.js has been started up. + */ + function load() { + + var scripts = [], + scriptsToLoad = 0; + + config.dependencies.forEach( function( s ) { + // Load if there's no condition or the condition is truthy + if( !s.condition || s.condition() ) { + if( s.async ) { + asyncDependencies.push( s ); + } + else { + scripts.push( s ); + } + } + } ); + + if( scripts.length ) { + scriptsToLoad = scripts.length; + + // Load synchronous scripts + scripts.forEach( function( s ) { + loadScript( s.src, function() { + + if( typeof s.callback === 'function' ) s.callback(); + + if( --scriptsToLoad === 0 ) { + initPlugins(); + } + + } ); + } ); + } + else { + initPlugins(); + } + + } + + /** + * Initializes our plugins and waits for them to be ready + * before proceeding. + */ + function initPlugins() { + + var pluginsToInitialize = Object.keys( plugins ).length; + + // If there are no plugins, skip this step + if( pluginsToInitialize === 0 ) { + loadAsyncDependencies(); + } + // ... otherwise initialize plugins + else { + + var afterPlugInitialized = function() { + if( --pluginsToInitialize === 0 ) { + loadAsyncDependencies(); + } + }; + + for( var i in plugins ) { + + var plugin = plugins[i]; + + // If the plugin has an 'init' method, invoke it + if( typeof plugin.init === 'function' ) { + var callback = plugin.init(); + + // If the plugin returned a Promise, wait for it + if( callback && typeof callback.then === 'function' ) { + callback.then( afterPlugInitialized ); + } + else { + afterPlugInitialized(); + } + } + else { + afterPlugInitialized(); + } + + } + + } + + } + + /** + * Loads all async reveal.js dependencies. + */ + function loadAsyncDependencies() { + + if( asyncDependencies.length ) { + asyncDependencies.forEach( function( s ) { + loadScript( s.src, s.callback ); + } ); + } + + start(); + + } + + /** + * Loads a JavaScript file from the given URL and executes it. + * + * @param {string} url Address of the .js file to load + * @param {function} callback Method to invoke when the script + * has loaded and executed + */ + function loadScript( url, callback ) { + + var script = document.createElement( 'script' ); + script.type = 'text/javascript'; + script.async = false; + script.defer = false; + script.src = url; + + if( callback ) { + + // Success callback + script.onload = script.onreadystatechange = function( event ) { + if( event.type === "load" || (/loaded|complete/.test( script.readyState ) ) ) { + + // Kill event listeners + script.onload = script.onreadystatechange = script.onerror = null; + + callback(); + + } + }; + + // Error callback + script.onerror = function( err ) { + + // Kill event listeners + script.onload = script.onreadystatechange = script.onerror = null; + + callback( new Error( 'Failed loading script: ' + script.src + '\n' + err) ); + + }; + + } + + // Append the script at the end of + var head = document.querySelector( 'head' ); + head.insertBefore( script, head.lastChild ); + + } + + /** + * Starts up reveal.js by binding input events and navigating + * to the current URL deeplink if there is one. + */ + function start() { + + loaded = true; + + // Make sure we've got all the DOM elements we need + setupDOM(); + + // Listen to messages posted to this window + setupPostMessage(); + + // Prevent the slides from being scrolled out of view + setupScrollPrevention(); + + // Resets all vertical slides so that only the first is visible + resetVerticalSlides(); + + // Updates the presentation to match the current configuration values + configure(); + + // Read the initial hash + readURL(); + + // Update all backgrounds + updateBackground( true ); + + // Notify listeners that the presentation is ready but use a 1ms + // timeout to ensure it's not fired synchronously after #initialize() + setTimeout( function() { + // Enable transitions now that we're loaded + dom.slides.classList.remove( 'no-transition' ); + + dom.wrapper.classList.add( 'ready' ); + + dispatchEvent( 'ready', { + 'indexh': indexh, + 'indexv': indexv, + 'currentSlide': currentSlide + } ); + }, 1 ); + + // Special setup and config is required when printing to PDF + if( isPrintingPDF() ) { + removeEventListeners(); + + // The document needs to have loaded for the PDF layout + // measurements to be accurate + if( document.readyState === 'complete' ) { + setupPDF(); + } + else { + window.addEventListener( 'load', setupPDF ); + } + } + + } + + /** + * Finds and stores references to DOM elements which are + * required by the presentation. If a required element is + * not found, it is created. + */ + function setupDOM() { + + // Prevent transitions while we're loading + dom.slides.classList.add( 'no-transition' ); + + if( isMobileDevice ) { + dom.wrapper.classList.add( 'no-hover' ); + } + else { + dom.wrapper.classList.remove( 'no-hover' ); + } + + if( /iphone/gi.test( UA ) ) { + dom.wrapper.classList.add( 'ua-iphone' ); + } + else { + dom.wrapper.classList.remove( 'ua-iphone' ); + } + + // Background element + dom.background = createSingletonNode( dom.wrapper, 'div', 'backgrounds', null ); + + // Progress bar + dom.progress = createSingletonNode( dom.wrapper, 'div', 'progress', '' ); + dom.progressbar = dom.progress.querySelector( 'span' ); + + // Arrow controls + dom.controls = createSingletonNode( dom.wrapper, 'aside', 'controls', + '' + + '' + + '' + + '' ); + + // Slide number + dom.slideNumber = createSingletonNode( dom.wrapper, 'div', 'slide-number', '' ); + + // Element containing notes that are visible to the audience + dom.speakerNotes = createSingletonNode( dom.wrapper, 'div', 'speaker-notes', null ); + dom.speakerNotes.setAttribute( 'data-prevent-swipe', '' ); + dom.speakerNotes.setAttribute( 'tabindex', '0' ); + + // Overlay graphic which is displayed during the paused mode + dom.pauseOverlay = createSingletonNode( dom.wrapper, 'div', 'pause-overlay', config.controls ? '' : null ); + + dom.wrapper.setAttribute( 'role', 'application' ); + + // There can be multiple instances of controls throughout the page + dom.controlsLeft = toArray( document.querySelectorAll( '.navigate-left' ) ); + dom.controlsRight = toArray( document.querySelectorAll( '.navigate-right' ) ); + dom.controlsUp = toArray( document.querySelectorAll( '.navigate-up' ) ); + dom.controlsDown = toArray( document.querySelectorAll( '.navigate-down' ) ); + dom.controlsPrev = toArray( document.querySelectorAll( '.navigate-prev' ) ); + dom.controlsNext = toArray( document.querySelectorAll( '.navigate-next' ) ); + + // The right and down arrows in the standard reveal.js controls + dom.controlsRightArrow = dom.controls.querySelector( '.navigate-right' ); + dom.controlsDownArrow = dom.controls.querySelector( '.navigate-down' ); + + dom.statusDiv = createStatusDiv(); + } + + /** + * Creates a hidden div with role aria-live to announce the + * current slide content. Hide the div off-screen to make it + * available only to Assistive Technologies. + * + * @return {HTMLElement} + */ + function createStatusDiv() { + + var statusDiv = document.getElementById( 'aria-status-div' ); + if( !statusDiv ) { + statusDiv = document.createElement( 'div' ); + statusDiv.style.position = 'absolute'; + statusDiv.style.height = '1px'; + statusDiv.style.width = '1px'; + statusDiv.style.overflow = 'hidden'; + statusDiv.style.clip = 'rect( 1px, 1px, 1px, 1px )'; + statusDiv.setAttribute( 'id', 'aria-status-div' ); + statusDiv.setAttribute( 'aria-live', 'polite' ); + statusDiv.setAttribute( 'aria-atomic','true' ); + dom.wrapper.appendChild( statusDiv ); + } + return statusDiv; + + } + + /** + * Converts the given HTML element into a string of text + * that can be announced to a screen reader. Hidden + * elements are excluded. + */ + function getStatusText( node ) { + + var text = ''; + + // Text node + if( node.nodeType === 3 ) { + text += node.textContent; + } + // Element node + else if( node.nodeType === 1 ) { + + var isAriaHidden = node.getAttribute( 'aria-hidden' ); + var isDisplayHidden = window.getComputedStyle( node )['display'] === 'none'; + if( isAriaHidden !== 'true' && !isDisplayHidden ) { + + toArray( node.childNodes ).forEach( function( child ) { + text += getStatusText( child ); + } ); + + } + + } + + return text; + + } + + /** + * Configures the presentation for printing to a static + * PDF. + */ + function setupPDF() { + + var slideSize = getComputedSlideSize( window.innerWidth, window.innerHeight ); + + // Dimensions of the PDF pages + var pageWidth = Math.floor( slideSize.width * ( 1 + config.margin ) ), + pageHeight = Math.floor( slideSize.height * ( 1 + config.margin ) ); + + // Dimensions of slides within the pages + var slideWidth = slideSize.width, + slideHeight = slideSize.height; + + // Let the browser know what page size we want to print + injectStyleSheet( '@page{size:'+ pageWidth +'px '+ pageHeight +'px; margin: 0px;}' ); + + // Limit the size of certain elements to the dimensions of the slide + injectStyleSheet( '.reveal section>img, .reveal section>video, .reveal section>iframe{max-width: '+ slideWidth +'px; max-height:'+ slideHeight +'px}' ); + + document.body.classList.add( 'print-pdf' ); + document.body.style.width = pageWidth + 'px'; + document.body.style.height = pageHeight + 'px'; + + // Make sure stretch elements fit on slide + layoutSlideContents( slideWidth, slideHeight ); + + // Add each slide's index as attributes on itself, we need these + // indices to generate slide numbers below + toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ).forEach( function( hslide, h ) { + hslide.setAttribute( 'data-index-h', h ); + + if( hslide.classList.contains( 'stack' ) ) { + toArray( hslide.querySelectorAll( 'section' ) ).forEach( function( vslide, v ) { + vslide.setAttribute( 'data-index-h', h ); + vslide.setAttribute( 'data-index-v', v ); + } ); + } + } ); + + // Slide and slide background layout + toArray( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) ).forEach( function( slide ) { + + // Vertical stacks are not centred since their section + // children will be + if( slide.classList.contains( 'stack' ) === false ) { + // Center the slide inside of the page, giving the slide some margin + var left = ( pageWidth - slideWidth ) / 2, + top = ( pageHeight - slideHeight ) / 2; + + var contentHeight = slide.scrollHeight; + var numberOfPages = Math.max( Math.ceil( contentHeight / pageHeight ), 1 ); + + // Adhere to configured pages per slide limit + numberOfPages = Math.min( numberOfPages, config.pdfMaxPagesPerSlide ); + + // Center slides vertically + if( numberOfPages === 1 && config.center || slide.classList.contains( 'center' ) ) { + top = Math.max( ( pageHeight - contentHeight ) / 2, 0 ); + } + + // Wrap the slide in a page element and hide its overflow + // so that no page ever flows onto another + var page = document.createElement( 'div' ); + page.className = 'pdf-page'; + page.style.height = ( ( pageHeight + config.pdfPageHeightOffset ) * numberOfPages ) + 'px'; + slide.parentNode.insertBefore( page, slide ); + page.appendChild( slide ); + + // Position the slide inside of the page + slide.style.left = left + 'px'; + slide.style.top = top + 'px'; + slide.style.width = slideWidth + 'px'; + + if( slide.slideBackgroundElement ) { + page.insertBefore( slide.slideBackgroundElement, slide ); + } + + // Inject notes if `showNotes` is enabled + if( config.showNotes ) { + + // Are there notes for this slide? + var notes = getSlideNotes( slide ); + if( notes ) { + + var notesSpacing = 8; + var notesLayout = typeof config.showNotes === 'string' ? config.showNotes : 'inline'; + var notesElement = document.createElement( 'div' ); + notesElement.classList.add( 'speaker-notes' ); + notesElement.classList.add( 'speaker-notes-pdf' ); + notesElement.setAttribute( 'data-layout', notesLayout ); + notesElement.innerHTML = notes; + + if( notesLayout === 'separate-page' ) { + page.parentNode.insertBefore( notesElement, page.nextSibling ); + } + else { + notesElement.style.left = notesSpacing + 'px'; + notesElement.style.bottom = notesSpacing + 'px'; + notesElement.style.width = ( pageWidth - notesSpacing*2 ) + 'px'; + page.appendChild( notesElement ); + } + + } + + } + + // Inject slide numbers if `slideNumbers` are enabled + if( config.slideNumber && /all|print/i.test( config.showSlideNumber ) ) { + var slideNumberH = parseInt( slide.getAttribute( 'data-index-h' ), 10 ) + 1, + slideNumberV = parseInt( slide.getAttribute( 'data-index-v' ), 10 ) + 1; + + var numberElement = document.createElement( 'div' ); + numberElement.classList.add( 'slide-number' ); + numberElement.classList.add( 'slide-number-pdf' ); + numberElement.innerHTML = formatSlideNumber( slideNumberH, '.', slideNumberV ); + page.appendChild( numberElement ); + } + + // Copy page and show fragments one after another + if( config.pdfSeparateFragments ) { + + // Each fragment 'group' is an array containing one or more + // fragments. Multiple fragments that appear at the same time + // are part of the same group. + var fragmentGroups = sortFragments( page.querySelectorAll( '.fragment' ), true ); + + var previousFragmentStep; + var previousPage; + + fragmentGroups.forEach( function( fragments ) { + + // Remove 'current-fragment' from the previous group + if( previousFragmentStep ) { + previousFragmentStep.forEach( function( fragment ) { + fragment.classList.remove( 'current-fragment' ); + } ); + } + + // Show the fragments for the current index + fragments.forEach( function( fragment ) { + fragment.classList.add( 'visible', 'current-fragment' ); + } ); + + // Create a separate page for the current fragment state + var clonedPage = page.cloneNode( true ); + page.parentNode.insertBefore( clonedPage, ( previousPage || page ).nextSibling ); + + previousFragmentStep = fragments; + previousPage = clonedPage; + + } ); + + // Reset the first/original page so that all fragments are hidden + fragmentGroups.forEach( function( fragments ) { + fragments.forEach( function( fragment ) { + fragment.classList.remove( 'visible', 'current-fragment' ); + } ); + } ); + + } + // Show all fragments + else { + toArray( page.querySelectorAll( '.fragment:not(.fade-out)' ) ).forEach( function( fragment ) { + fragment.classList.add( 'visible' ); + } ); + } + + } + + } ); + + // Notify subscribers that the PDF layout is good to go + dispatchEvent( 'pdf-ready' ); + + } + + /** + * This is an unfortunate necessity. Some actions – such as + * an input field being focused in an iframe or using the + * keyboard to expand text selection beyond the bounds of + * a slide – can trigger our content to be pushed out of view. + * This scrolling can not be prevented by hiding overflow in + * CSS (we already do) so we have to resort to repeatedly + * checking if the slides have been offset :( + */ + function setupScrollPrevention() { + + setInterval( function() { + if( dom.wrapper.scrollTop !== 0 || dom.wrapper.scrollLeft !== 0 ) { + dom.wrapper.scrollTop = 0; + dom.wrapper.scrollLeft = 0; + } + }, 1000 ); + + } + + /** + * Creates an HTML element and returns a reference to it. + * If the element already exists the existing instance will + * be returned. + * + * @param {HTMLElement} container + * @param {string} tagname + * @param {string} classname + * @param {string} innerHTML + * + * @return {HTMLElement} + */ + function createSingletonNode( container, tagname, classname, innerHTML ) { + + // Find all nodes matching the description + var nodes = container.querySelectorAll( '.' + classname ); + + // Check all matches to find one which is a direct child of + // the specified container + for( var i = 0; i < nodes.length; i++ ) { + var testNode = nodes[i]; + if( testNode.parentNode === container ) { + return testNode; + } + } + + // If no node was found, create it now + var node = document.createElement( tagname ); + node.className = classname; + if( typeof innerHTML === 'string' ) { + node.innerHTML = innerHTML; + } + container.appendChild( node ); + + return node; + + } + + /** + * Creates the slide background elements and appends them + * to the background container. One element is created per + * slide no matter if the given slide has visible background. + */ + function createBackgrounds() { + + var printMode = isPrintingPDF(); + + // Clear prior backgrounds + dom.background.innerHTML = ''; + dom.background.classList.add( 'no-transition' ); + + // Iterate over all horizontal slides + toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ).forEach( function( slideh ) { + + var backgroundStack = createBackground( slideh, dom.background ); + + // Iterate over all vertical slides + toArray( slideh.querySelectorAll( 'section' ) ).forEach( function( slidev ) { + + createBackground( slidev, backgroundStack ); + + backgroundStack.classList.add( 'stack' ); + + } ); + + } ); + + // Add parallax background if specified + if( config.parallaxBackgroundImage ) { + + dom.background.style.backgroundImage = 'url("' + config.parallaxBackgroundImage + '")'; + dom.background.style.backgroundSize = config.parallaxBackgroundSize; + dom.background.style.backgroundRepeat = config.parallaxBackgroundRepeat; + dom.background.style.backgroundPosition = config.parallaxBackgroundPosition; + + // Make sure the below properties are set on the element - these properties are + // needed for proper transitions to be set on the element via CSS. To remove + // annoying background slide-in effect when the presentation starts, apply + // these properties after short time delay + setTimeout( function() { + dom.wrapper.classList.add( 'has-parallax-background' ); + }, 1 ); + + } + else { + + dom.background.style.backgroundImage = ''; + dom.wrapper.classList.remove( 'has-parallax-background' ); + + } + + } + + /** + * Creates a background for the given slide. + * + * @param {HTMLElement} slide + * @param {HTMLElement} container The element that the background + * should be appended to + * @return {HTMLElement} New background div + */ + function createBackground( slide, container ) { + + + // Main slide background element + var element = document.createElement( 'div' ); + element.className = 'slide-background ' + slide.className.replace( /present|past|future/, '' ); + + // Inner background element that wraps images/videos/iframes + var contentElement = document.createElement( 'div' ); + contentElement.className = 'slide-background-content'; + + element.appendChild( contentElement ); + container.appendChild( element ); + + slide.slideBackgroundElement = element; + slide.slideBackgroundContentElement = contentElement; + + // Syncs the background to reflect all current background settings + syncBackground( slide ); + + return element; + + } + + /** + * Renders all of the visual properties of a slide background + * based on the various background attributes. + * + * @param {HTMLElement} slide + */ + function syncBackground( slide ) { + + var element = slide.slideBackgroundElement, + contentElement = slide.slideBackgroundContentElement; + + // Reset the prior background state in case this is not the + // initial sync + slide.classList.remove( 'has-dark-background' ); + slide.classList.remove( 'has-light-background' ); + + element.removeAttribute( 'data-loaded' ); + element.removeAttribute( 'data-background-hash' ); + element.removeAttribute( 'data-background-size' ); + element.removeAttribute( 'data-background-transition' ); + element.style.backgroundColor = ''; + + contentElement.style.backgroundSize = ''; + contentElement.style.backgroundRepeat = ''; + contentElement.style.backgroundPosition = ''; + contentElement.style.backgroundImage = ''; + contentElement.style.opacity = ''; + contentElement.innerHTML = ''; + + var data = { + background: slide.getAttribute( 'data-background' ), + backgroundSize: slide.getAttribute( 'data-background-size' ), + backgroundImage: slide.getAttribute( 'data-background-image' ), + backgroundVideo: slide.getAttribute( 'data-background-video' ), + backgroundIframe: slide.getAttribute( 'data-background-iframe' ), + backgroundColor: slide.getAttribute( 'data-background-color' ), + backgroundRepeat: slide.getAttribute( 'data-background-repeat' ), + backgroundPosition: slide.getAttribute( 'data-background-position' ), + backgroundTransition: slide.getAttribute( 'data-background-transition' ), + backgroundOpacity: slide.getAttribute( 'data-background-opacity' ) + }; + + if( data.background ) { + // Auto-wrap image urls in url(...) + if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp)([?#\s]|$)/gi.test( data.background ) ) { + slide.setAttribute( 'data-background-image', data.background ); + } + else { + element.style.background = data.background; + } + } + + // Create a hash for this combination of background settings. + // This is used to determine when two slide backgrounds are + // the same. + if( data.background || data.backgroundColor || data.backgroundImage || data.backgroundVideo || data.backgroundIframe ) { + element.setAttribute( 'data-background-hash', data.background + + data.backgroundSize + + data.backgroundImage + + data.backgroundVideo + + data.backgroundIframe + + data.backgroundColor + + data.backgroundRepeat + + data.backgroundPosition + + data.backgroundTransition + + data.backgroundOpacity ); + } + + // Additional and optional background properties + if( data.backgroundSize ) element.setAttribute( 'data-background-size', data.backgroundSize ); + if( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor; + if( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition ); + + // Background image options are set on the content wrapper + if( data.backgroundSize ) contentElement.style.backgroundSize = data.backgroundSize; + if( data.backgroundRepeat ) contentElement.style.backgroundRepeat = data.backgroundRepeat; + if( data.backgroundPosition ) contentElement.style.backgroundPosition = data.backgroundPosition; + if( data.backgroundOpacity ) contentElement.style.opacity = data.backgroundOpacity; + + // If this slide has a background color, we add a class that + // signals if it is light or dark. If the slide has no background + // color, no class will be added + var contrastColor = data.backgroundColor; + + // If no bg color was found, check the computed background + if( !contrastColor ) { + var computedBackgroundStyle = window.getComputedStyle( element ); + if( computedBackgroundStyle && computedBackgroundStyle.backgroundColor ) { + contrastColor = computedBackgroundStyle.backgroundColor; + } + } + + if( contrastColor ) { + var rgb = colorToRgb( contrastColor ); + + // Ignore fully transparent backgrounds. Some browsers return + // rgba(0,0,0,0) when reading the computed background color of + // an element with no background + if( rgb && rgb.a !== 0 ) { + if( colorBrightness( contrastColor ) < 128 ) { + slide.classList.add( 'has-dark-background' ); + } + else { + slide.classList.add( 'has-light-background' ); + } + } + } + + } + + /** + * Registers a listener to postMessage events, this makes it + * possible to call all reveal.js API methods from another + * window. For example: + * + * revealWindow.postMessage( JSON.stringify({ + * method: 'slide', + * args: [ 2 ] + * }), '*' ); + */ + function setupPostMessage() { + + if( config.postMessage ) { + window.addEventListener( 'message', function ( event ) { + var data = event.data; + + // Make sure we're dealing with JSON + if( typeof data === 'string' && data.charAt( 0 ) === '{' && data.charAt( data.length - 1 ) === '}' ) { + data = JSON.parse( data ); + + // Check if the requested method can be found + if( data.method && typeof Reveal[data.method] === 'function' ) { + Reveal[data.method].apply( Reveal, data.args ); + } + } + }, false ); + } + + } + + /** + * Applies the configuration settings from the config + * object. May be called multiple times. + * + * @param {object} options + */ + function configure( options ) { + + var oldTransition = config.transition; + + // New config options may be passed when this method + // is invoked through the API after initialization + if( typeof options === 'object' ) extend( config, options ); + + // Abort if reveal.js hasn't finished loading, config + // changes will be applied automatically once loading + // finishes + if( loaded === false ) return; + + var numberOfSlides = dom.wrapper.querySelectorAll( SLIDES_SELECTOR ).length; + + // Remove the previously configured transition class + dom.wrapper.classList.remove( oldTransition ); + + // Force linear transition based on browser capabilities + if( features.transforms3d === false ) config.transition = 'linear'; + + dom.wrapper.classList.add( config.transition ); + + dom.wrapper.setAttribute( 'data-transition-speed', config.transitionSpeed ); + dom.wrapper.setAttribute( 'data-background-transition', config.backgroundTransition ); + + dom.controls.style.display = config.controls ? 'block' : 'none'; + dom.progress.style.display = config.progress ? 'block' : 'none'; + + dom.controls.setAttribute( 'data-controls-layout', config.controlsLayout ); + dom.controls.setAttribute( 'data-controls-back-arrows', config.controlsBackArrows ); + + if( config.shuffle ) { + shuffle(); + } + + if( config.rtl ) { + dom.wrapper.classList.add( 'rtl' ); + } + else { + dom.wrapper.classList.remove( 'rtl' ); + } + + if( config.center ) { + dom.wrapper.classList.add( 'center' ); + } + else { + dom.wrapper.classList.remove( 'center' ); + } + + // Exit the paused mode if it was configured off + if( config.pause === false ) { + resume(); + } + + if( config.showNotes ) { + dom.speakerNotes.setAttribute( 'data-layout', typeof config.showNotes === 'string' ? config.showNotes : 'inline' ); + } + + if( config.mouseWheel ) { + document.addEventListener( 'DOMMouseScroll', onDocumentMouseScroll, false ); // FF + document.addEventListener( 'mousewheel', onDocumentMouseScroll, false ); + } + else { + document.removeEventListener( 'DOMMouseScroll', onDocumentMouseScroll, false ); // FF + document.removeEventListener( 'mousewheel', onDocumentMouseScroll, false ); + } + + // Rolling 3D links + if( config.rollingLinks ) { + enableRollingLinks(); + } + else { + disableRollingLinks(); + } + + // Auto-hide the mouse pointer when its inactive + if( config.hideInactiveCursor ) { + document.addEventListener( 'mousemove', onDocumentCursorActive, false ); + document.addEventListener( 'mousedown', onDocumentCursorActive, false ); + } + else { + showCursor(); + + document.removeEventListener( 'mousemove', onDocumentCursorActive, false ); + document.removeEventListener( 'mousedown', onDocumentCursorActive, false ); + } + + // Iframe link previews + if( config.previewLinks ) { + enablePreviewLinks(); + disablePreviewLinks( '[data-preview-link=false]' ); + } + else { + disablePreviewLinks(); + enablePreviewLinks( '[data-preview-link]:not([data-preview-link=false])' ); + } + + // Remove existing auto-slide controls + if( autoSlidePlayer ) { + autoSlidePlayer.destroy(); + autoSlidePlayer = null; + } + + // Generate auto-slide controls if needed + if( numberOfSlides > 1 && config.autoSlide && config.autoSlideStoppable && features.canvas && features.requestAnimationFrame ) { + autoSlidePlayer = new Playback( dom.wrapper, function() { + return Math.min( Math.max( ( Date.now() - autoSlideStartTime ) / autoSlide, 0 ), 1 ); + } ); + + autoSlidePlayer.on( 'click', onAutoSlidePlayerClick ); + autoSlidePaused = false; + } + + // When fragments are turned off they should be visible + if( config.fragments === false ) { + toArray( dom.slides.querySelectorAll( '.fragment' ) ).forEach( function( element ) { + element.classList.add( 'visible' ); + element.classList.remove( 'current-fragment' ); + } ); + } + + // Slide numbers + var slideNumberDisplay = 'none'; + if( config.slideNumber && !isPrintingPDF() ) { + if( config.showSlideNumber === 'all' ) { + slideNumberDisplay = 'block'; + } + else if( config.showSlideNumber === 'speaker' && isSpeakerNotes() ) { + slideNumberDisplay = 'block'; + } + } + + dom.slideNumber.style.display = slideNumberDisplay; + + // Add the navigation mode to the DOM so we can adjust styling + if( config.navigationMode !== 'default' ) { + dom.wrapper.setAttribute( 'data-navigation-mode', config.navigationMode ); + } + else { + dom.wrapper.removeAttribute( 'data-navigation-mode' ); + } + + // Define our contextual list of keyboard shortcuts + if( config.navigationMode === 'linear' ) { + keyboardShortcuts['→ , ↓ , SPACE , N , L , J'] = 'Next slide'; + keyboardShortcuts['← , ↑ , P , H , K'] = 'Previous slide'; + } + else { + keyboardShortcuts['N , SPACE'] = 'Next slide'; + keyboardShortcuts['P'] = 'Previous slide'; + keyboardShortcuts['← , H'] = 'Navigate left'; + keyboardShortcuts['→ , L'] = 'Navigate right'; + keyboardShortcuts['↑ , K'] = 'Navigate up'; + keyboardShortcuts['↓ , J'] = 'Navigate down'; + } + + keyboardShortcuts['Home , ⌘/CTRL ←'] = 'First slide'; + keyboardShortcuts['End , ⌘/CTRL →'] = 'Last slide'; + keyboardShortcuts['B , .'] = 'Pause'; + keyboardShortcuts['F'] = 'Fullscreen'; + keyboardShortcuts['ESC, O'] = 'Slide overview'; + + sync(); + + } + + /** + * Binds all event listeners. + */ + function addEventListeners() { + + eventsAreBound = true; + + window.addEventListener( 'hashchange', onWindowHashChange, false ); + window.addEventListener( 'resize', onWindowResize, false ); + + if( config.touch ) { + if( 'onpointerdown' in window ) { + // Use W3C pointer events + dom.wrapper.addEventListener( 'pointerdown', onPointerDown, false ); + dom.wrapper.addEventListener( 'pointermove', onPointerMove, false ); + dom.wrapper.addEventListener( 'pointerup', onPointerUp, false ); + } + else if( window.navigator.msPointerEnabled ) { + // IE 10 uses prefixed version of pointer events + dom.wrapper.addEventListener( 'MSPointerDown', onPointerDown, false ); + dom.wrapper.addEventListener( 'MSPointerMove', onPointerMove, false ); + dom.wrapper.addEventListener( 'MSPointerUp', onPointerUp, false ); + } + else { + // Fall back to touch events + dom.wrapper.addEventListener( 'touchstart', onTouchStart, false ); + dom.wrapper.addEventListener( 'touchmove', onTouchMove, false ); + dom.wrapper.addEventListener( 'touchend', onTouchEnd, false ); + } + } + + if( config.keyboard ) { + document.addEventListener( 'keydown', onDocumentKeyDown, false ); + document.addEventListener( 'keypress', onDocumentKeyPress, false ); + } + + if( config.progress && dom.progress ) { + dom.progress.addEventListener( 'click', onProgressClicked, false ); + } + + dom.pauseOverlay.addEventListener( 'click', resume, false ); + + if( config.focusBodyOnPageVisibilityChange ) { + var visibilityChange; + + if( 'hidden' in document ) { + visibilityChange = 'visibilitychange'; + } + else if( 'msHidden' in document ) { + visibilityChange = 'msvisibilitychange'; + } + else if( 'webkitHidden' in document ) { + visibilityChange = 'webkitvisibilitychange'; + } + + if( visibilityChange ) { + document.addEventListener( visibilityChange, onPageVisibilityChange, false ); + } + } + + // Listen to both touch and click events, in case the device + // supports both + var pointerEvents = [ 'touchstart', 'click' ]; + + // Only support touch for Android, fixes double navigations in + // stock browser + if( UA.match( /android/gi ) ) { + pointerEvents = [ 'touchstart' ]; + } + + pointerEvents.forEach( function( eventName ) { + dom.controlsLeft.forEach( function( el ) { el.addEventListener( eventName, onNavigateLeftClicked, false ); } ); + dom.controlsRight.forEach( function( el ) { el.addEventListener( eventName, onNavigateRightClicked, false ); } ); + dom.controlsUp.forEach( function( el ) { el.addEventListener( eventName, onNavigateUpClicked, false ); } ); + dom.controlsDown.forEach( function( el ) { el.addEventListener( eventName, onNavigateDownClicked, false ); } ); + dom.controlsPrev.forEach( function( el ) { el.addEventListener( eventName, onNavigatePrevClicked, false ); } ); + dom.controlsNext.forEach( function( el ) { el.addEventListener( eventName, onNavigateNextClicked, false ); } ); + } ); + + } + + /** + * Unbinds all event listeners. + */ + function removeEventListeners() { + + eventsAreBound = false; + + document.removeEventListener( 'keydown', onDocumentKeyDown, false ); + document.removeEventListener( 'keypress', onDocumentKeyPress, false ); + window.removeEventListener( 'hashchange', onWindowHashChange, false ); + window.removeEventListener( 'resize', onWindowResize, false ); + + dom.wrapper.removeEventListener( 'pointerdown', onPointerDown, false ); + dom.wrapper.removeEventListener( 'pointermove', onPointerMove, false ); + dom.wrapper.removeEventListener( 'pointerup', onPointerUp, false ); + + dom.wrapper.removeEventListener( 'MSPointerDown', onPointerDown, false ); + dom.wrapper.removeEventListener( 'MSPointerMove', onPointerMove, false ); + dom.wrapper.removeEventListener( 'MSPointerUp', onPointerUp, false ); + + dom.wrapper.removeEventListener( 'touchstart', onTouchStart, false ); + dom.wrapper.removeEventListener( 'touchmove', onTouchMove, false ); + dom.wrapper.removeEventListener( 'touchend', onTouchEnd, false ); + + dom.pauseOverlay.removeEventListener( 'click', resume, false ); + + if ( config.progress && dom.progress ) { + dom.progress.removeEventListener( 'click', onProgressClicked, false ); + } + + [ 'touchstart', 'click' ].forEach( function( eventName ) { + dom.controlsLeft.forEach( function( el ) { el.removeEventListener( eventName, onNavigateLeftClicked, false ); } ); + dom.controlsRight.forEach( function( el ) { el.removeEventListener( eventName, onNavigateRightClicked, false ); } ); + dom.controlsUp.forEach( function( el ) { el.removeEventListener( eventName, onNavigateUpClicked, false ); } ); + dom.controlsDown.forEach( function( el ) { el.removeEventListener( eventName, onNavigateDownClicked, false ); } ); + dom.controlsPrev.forEach( function( el ) { el.removeEventListener( eventName, onNavigatePrevClicked, false ); } ); + dom.controlsNext.forEach( function( el ) { el.removeEventListener( eventName, onNavigateNextClicked, false ); } ); + } ); + + } + + /** + * Registers a new plugin with this reveal.js instance. + * + * reveal.js waits for all regisered plugins to initialize + * before considering itself ready, as long as the plugin + * is registered before calling `Reveal.initialize()`. + */ + function registerPlugin( id, plugin ) { + + if( plugins[id] === undefined ) { + plugins[id] = plugin; + + // If a plugin is registered after reveal.js is loaded, + // initialize it right away + if( loaded && typeof plugin.init === 'function' ) { + plugin.init(); + } + } + else { + console.warn( 'reveal.js: "'+ id +'" plugin has already been registered' ); + } + + } + + /** + * Checks if a specific plugin has been registered. + * + * @param {String} id Unique plugin identifier + */ + function hasPlugin( id ) { + + return !!plugins[id]; + + } + + /** + * Returns the specific plugin instance, if a plugin + * with the given ID has been registered. + * + * @param {String} id Unique plugin identifier + */ + function getPlugin( id ) { + + return plugins[id]; + + } + + /** + * Add a custom key binding with optional description to + * be added to the help screen. + */ + function addKeyBinding( binding, callback ) { + + if( typeof binding === 'object' && binding.keyCode ) { + registeredKeyBindings[binding.keyCode] = { + callback: callback, + key: binding.key, + description: binding.description + }; + } + else { + registeredKeyBindings[binding] = { + callback: callback, + key: null, + description: null + }; + } + + } + + /** + * Removes the specified custom key binding. + */ + function removeKeyBinding( keyCode ) { + + delete registeredKeyBindings[keyCode]; + + } + + /** + * Extend object a with the properties of object b. + * If there's a conflict, object b takes precedence. + * + * @param {object} a + * @param {object} b + */ + function extend( a, b ) { + + for( var i in b ) { + a[ i ] = b[ i ]; + } + + return a; + + } + + /** + * Converts the target object to an array. + * + * @param {object} o + * @return {object[]} + */ + function toArray( o ) { + + return Array.prototype.slice.call( o ); + + } + + /** + * Utility for deserializing a value. + * + * @param {*} value + * @return {*} + */ + function deserialize( value ) { + + if( typeof value === 'string' ) { + if( value === 'null' ) return null; + else if( value === 'true' ) return true; + else if( value === 'false' ) return false; + else if( value.match( /^-?[\d\.]+$/ ) ) return parseFloat( value ); + } + + return value; + + } + + /** + * Measures the distance in pixels between point a + * and point b. + * + * @param {object} a point with x/y properties + * @param {object} b point with x/y properties + * + * @return {number} + */ + function distanceBetween( a, b ) { + + var dx = a.x - b.x, + dy = a.y - b.y; + + return Math.sqrt( dx*dx + dy*dy ); + + } + + /** + * Applies a CSS transform to the target element. + * + * @param {HTMLElement} element + * @param {string} transform + */ + function transformElement( element, transform ) { + + element.style.WebkitTransform = transform; + element.style.MozTransform = transform; + element.style.msTransform = transform; + element.style.transform = transform; + + } + + /** + * Applies CSS transforms to the slides container. The container + * is transformed from two separate sources: layout and the overview + * mode. + * + * @param {object} transforms + */ + function transformSlides( transforms ) { + + // Pick up new transforms from arguments + if( typeof transforms.layout === 'string' ) slidesTransform.layout = transforms.layout; + if( typeof transforms.overview === 'string' ) slidesTransform.overview = transforms.overview; + + // Apply the transforms to the slides container + if( slidesTransform.layout ) { + transformElement( dom.slides, slidesTransform.layout + ' ' + slidesTransform.overview ); + } + else { + transformElement( dom.slides, slidesTransform.overview ); + } + + } + + /** + * Injects the given CSS styles into the DOM. + * + * @param {string} value + */ + function injectStyleSheet( value ) { + + var tag = document.createElement( 'style' ); + tag.type = 'text/css'; + if( tag.styleSheet ) { + tag.styleSheet.cssText = value; + } + else { + tag.appendChild( document.createTextNode( value ) ); + } + document.getElementsByTagName( 'head' )[0].appendChild( tag ); + + } + + /** + * Find the closest parent that matches the given + * selector. + * + * @param {HTMLElement} target The child element + * @param {String} selector The CSS selector to match + * the parents against + * + * @return {HTMLElement} The matched parent or null + * if no matching parent was found + */ + function closestParent( target, selector ) { + + var parent = target.parentNode; + + while( parent ) { + + // There's some overhead doing this each time, we don't + // want to rewrite the element prototype but should still + // be enough to feature detect once at startup... + var matchesMethod = parent.matches || parent.matchesSelector || parent.msMatchesSelector; + + // If we find a match, we're all set + if( matchesMethod && matchesMethod.call( parent, selector ) ) { + return parent; + } + + // Keep searching + parent = parent.parentNode; + + } + + return null; + + } + + /** + * Converts various color input formats to an {r:0,g:0,b:0} object. + * + * @param {string} color The string representation of a color + * @example + * colorToRgb('#000'); + * @example + * colorToRgb('#000000'); + * @example + * colorToRgb('rgb(0,0,0)'); + * @example + * colorToRgb('rgba(0,0,0)'); + * + * @return {{r: number, g: number, b: number, [a]: number}|null} + */ + function colorToRgb( color ) { + + var hex3 = color.match( /^#([0-9a-f]{3})$/i ); + if( hex3 && hex3[1] ) { + hex3 = hex3[1]; + return { + r: parseInt( hex3.charAt( 0 ), 16 ) * 0x11, + g: parseInt( hex3.charAt( 1 ), 16 ) * 0x11, + b: parseInt( hex3.charAt( 2 ), 16 ) * 0x11 + }; + } + + var hex6 = color.match( /^#([0-9a-f]{6})$/i ); + if( hex6 && hex6[1] ) { + hex6 = hex6[1]; + return { + r: parseInt( hex6.substr( 0, 2 ), 16 ), + g: parseInt( hex6.substr( 2, 2 ), 16 ), + b: parseInt( hex6.substr( 4, 2 ), 16 ) + }; + } + + var rgb = color.match( /^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i ); + if( rgb ) { + return { + r: parseInt( rgb[1], 10 ), + g: parseInt( rgb[2], 10 ), + b: parseInt( rgb[3], 10 ) + }; + } + + var rgba = color.match( /^rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\,\s*([\d]+|[\d]*.[\d]+)\s*\)$/i ); + if( rgba ) { + return { + r: parseInt( rgba[1], 10 ), + g: parseInt( rgba[2], 10 ), + b: parseInt( rgba[3], 10 ), + a: parseFloat( rgba[4] ) + }; + } + + return null; + + } + + /** + * Calculates brightness on a scale of 0-255. + * + * @param {string} color See colorToRgb for supported formats. + * @see {@link colorToRgb} + */ + function colorBrightness( color ) { + + if( typeof color === 'string' ) color = colorToRgb( color ); + + if( color ) { + return ( color.r * 299 + color.g * 587 + color.b * 114 ) / 1000; + } + + return null; + + } + + /** + * Returns the remaining height within the parent of the + * target element. + * + * remaining height = [ configured parent height ] - [ current parent height ] + * + * @param {HTMLElement} element + * @param {number} [height] + */ + function getRemainingHeight( element, height ) { + + height = height || 0; + + if( element ) { + var newHeight, oldHeight = element.style.height; + + // Change the .stretch element height to 0 in order find the height of all + // the other elements + element.style.height = '0px'; + + // In Overview mode, the parent (.slide) height is set of 700px. + // Restore it temporarily to its natural height. + element.parentNode.style.height = 'auto'; + + newHeight = height - element.parentNode.offsetHeight; + + // Restore the old height, just in case + element.style.height = oldHeight + 'px'; + + // Clear the parent (.slide) height. .removeProperty works in IE9+ + element.parentNode.style.removeProperty('height'); + + return newHeight; + } + + return height; + + } + + /** + * Checks if this instance is being used to print a PDF. + */ + function isPrintingPDF() { + + return ( /print-pdf/gi ).test( window.location.search ); + + } + + /** + * Hides the address bar if we're on a mobile device. + */ + function hideAddressBar() { + + if( config.hideAddressBar && isMobileDevice ) { + // Events that should trigger the address bar to hide + window.addEventListener( 'load', removeAddressBar, false ); + window.addEventListener( 'orientationchange', removeAddressBar, false ); + } + + } + + /** + * Causes the address bar to hide on mobile devices, + * more vertical space ftw. + */ + function removeAddressBar() { + + setTimeout( function() { + window.scrollTo( 0, 1 ); + }, 10 ); + + } + + /** + * Dispatches an event of the specified type from the + * reveal DOM element. + */ + function dispatchEvent( type, args ) { + + var event = document.createEvent( 'HTMLEvents', 1, 2 ); + event.initEvent( type, true, true ); + extend( event, args ); + dom.wrapper.dispatchEvent( event ); + + // If we're in an iframe, post each reveal.js event to the + // parent window. Used by the notes plugin + if( config.postMessageEvents && window.parent !== window.self ) { + window.parent.postMessage( JSON.stringify({ namespace: 'reveal', eventName: type, state: getState() }), '*' ); + } + + } + + /** + * Wrap all links in 3D goodness. + */ + function enableRollingLinks() { + + if( features.transforms3d && !( 'msPerspective' in document.body.style ) ) { + var anchors = dom.wrapper.querySelectorAll( SLIDES_SELECTOR + ' a' ); + + for( var i = 0, len = anchors.length; i < len; i++ ) { + var anchor = anchors[i]; + + if( anchor.textContent && !anchor.querySelector( '*' ) && ( !anchor.className || !anchor.classList.contains( anchor, 'roll' ) ) ) { + var span = document.createElement('span'); + span.setAttribute('data-title', anchor.text); + span.innerHTML = anchor.innerHTML; + + anchor.classList.add( 'roll' ); + anchor.innerHTML = ''; + anchor.appendChild(span); + } + } + } + + } + + /** + * Unwrap all 3D links. + */ + function disableRollingLinks() { + + var anchors = dom.wrapper.querySelectorAll( SLIDES_SELECTOR + ' a.roll' ); + + for( var i = 0, len = anchors.length; i < len; i++ ) { + var anchor = anchors[i]; + var span = anchor.querySelector( 'span' ); + + if( span ) { + anchor.classList.remove( 'roll' ); + anchor.innerHTML = span.innerHTML; + } + } + + } + + /** + * Bind preview frame links. + * + * @param {string} [selector=a] - selector for anchors + */ + function enablePreviewLinks( selector ) { + + var anchors = toArray( document.querySelectorAll( selector ? selector : 'a' ) ); + + anchors.forEach( function( element ) { + if( /^(http|www)/gi.test( element.getAttribute( 'href' ) ) ) { + element.addEventListener( 'click', onPreviewLinkClicked, false ); + } + } ); + + } + + /** + * Unbind preview frame links. + */ + function disablePreviewLinks( selector ) { + + var anchors = toArray( document.querySelectorAll( selector ? selector : 'a' ) ); + + anchors.forEach( function( element ) { + if( /^(http|www)/gi.test( element.getAttribute( 'href' ) ) ) { + element.removeEventListener( 'click', onPreviewLinkClicked, false ); + } + } ); + + } + + /** + * Opens a preview window for the target URL. + * + * @param {string} url - url for preview iframe src + */ + function showPreview( url ) { + + closeOverlay(); + + dom.overlay = document.createElement( 'div' ); + dom.overlay.classList.add( 'overlay' ); + dom.overlay.classList.add( 'overlay-preview' ); + dom.wrapper.appendChild( dom.overlay ); + + dom.overlay.innerHTML = [ + '
    ', + '', + '', + '
    ', + '
    ', + '
    ', + '', + '', + 'Unable to load iframe. This is likely due to the site\'s policy (x-frame-options).', + '', + '
    ' + ].join(''); + + dom.overlay.querySelector( 'iframe' ).addEventListener( 'load', function( event ) { + dom.overlay.classList.add( 'loaded' ); + }, false ); + + dom.overlay.querySelector( '.close' ).addEventListener( 'click', function( event ) { + closeOverlay(); + event.preventDefault(); + }, false ); + + dom.overlay.querySelector( '.external' ).addEventListener( 'click', function( event ) { + closeOverlay(); + }, false ); + + setTimeout( function() { + dom.overlay.classList.add( 'visible' ); + }, 1 ); + + } + + /** + * Open or close help overlay window. + * + * @param {Boolean} [override] Flag which overrides the + * toggle logic and forcibly sets the desired state. True means + * help is open, false means it's closed. + */ + function toggleHelp( override ){ + + if( typeof override === 'boolean' ) { + override ? showHelp() : closeOverlay(); + } + else { + if( dom.overlay ) { + closeOverlay(); + } + else { + showHelp(); + } + } + } + + /** + * Opens an overlay window with help material. + */ + function showHelp() { + + if( config.help ) { + + closeOverlay(); + + dom.overlay = document.createElement( 'div' ); + dom.overlay.classList.add( 'overlay' ); + dom.overlay.classList.add( 'overlay-help' ); + dom.wrapper.appendChild( dom.overlay ); + + var html = '

    Keyboard Shortcuts


    '; + + html += ''; + for( var key in keyboardShortcuts ) { + html += ''; + } + + // Add custom key bindings that have associated descriptions + for( var binding in registeredKeyBindings ) { + if( registeredKeyBindings[binding].key && registeredKeyBindings[binding].description ) { + html += ''; + } + } + + html += '
    KEYACTION
    ' + key + '' + keyboardShortcuts[ key ] + '
    ' + registeredKeyBindings[binding].key + '' + registeredKeyBindings[binding].description + '
    '; + + dom.overlay.innerHTML = [ + '
    ', + '', + '
    ', + '
    ', + '
    '+ html +'
    ', + '
    ' + ].join(''); + + dom.overlay.querySelector( '.close' ).addEventListener( 'click', function( event ) { + closeOverlay(); + event.preventDefault(); + }, false ); + + setTimeout( function() { + dom.overlay.classList.add( 'visible' ); + }, 1 ); + + } + + } + + /** + * Closes any currently open overlay. + */ + function closeOverlay() { + + if( dom.overlay ) { + dom.overlay.parentNode.removeChild( dom.overlay ); + dom.overlay = null; + } + + } + + /** + * Applies JavaScript-controlled layout rules to the + * presentation. + */ + function layout() { + + if( dom.wrapper && !isPrintingPDF() ) { + + if( !config.disableLayout ) { + + // On some mobile devices '100vh' is taller than the visible + // viewport which leads to part of the presentation being + // cut off. To work around this we define our own '--vh' custom + // property where 100x adds up to the correct height. + // + // https://css-tricks.com/the-trick-to-viewport-units-on-mobile/ + if( isMobileDevice ) { + document.documentElement.style.setProperty( '--vh', ( window.innerHeight * 0.01 ) + 'px' ); + } + + var size = getComputedSlideSize(); + + var oldScale = scale; + + // Layout the contents of the slides + layoutSlideContents( config.width, config.height ); + + dom.slides.style.width = size.width + 'px'; + dom.slides.style.height = size.height + 'px'; + + // Determine scale of content to fit within available space + scale = Math.min( size.presentationWidth / size.width, size.presentationHeight / size.height ); + + // Respect max/min scale settings + scale = Math.max( scale, config.minScale ); + scale = Math.min( scale, config.maxScale ); + + // Don't apply any scaling styles if scale is 1 + if( scale === 1 ) { + dom.slides.style.zoom = ''; + dom.slides.style.left = ''; + dom.slides.style.top = ''; + dom.slides.style.bottom = ''; + dom.slides.style.right = ''; + transformSlides( { layout: '' } ); + } + else { + // Prefer zoom for scaling up so that content remains crisp. + // Don't use zoom to scale down since that can lead to shifts + // in text layout/line breaks. + if( scale > 1 && features.zoom ) { + dom.slides.style.zoom = scale; + dom.slides.style.left = ''; + dom.slides.style.top = ''; + dom.slides.style.bottom = ''; + dom.slides.style.right = ''; + transformSlides( { layout: '' } ); + } + // Apply scale transform as a fallback + else { + dom.slides.style.zoom = ''; + dom.slides.style.left = '50%'; + dom.slides.style.top = '50%'; + dom.slides.style.bottom = 'auto'; + dom.slides.style.right = 'auto'; + transformSlides( { layout: 'translate(-50%, -50%) scale('+ scale +')' } ); + } + } + + // Select all slides, vertical and horizontal + var slides = toArray( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) ); + + for( var i = 0, len = slides.length; i < len; i++ ) { + var slide = slides[ i ]; + + // Don't bother updating invisible slides + if( slide.style.display === 'none' ) { + continue; + } + + if( config.center || slide.classList.contains( 'center' ) ) { + // Vertical stacks are not centred since their section + // children will be + if( slide.classList.contains( 'stack' ) ) { + slide.style.top = 0; + } + else { + slide.style.top = Math.max( ( size.height - slide.scrollHeight ) / 2, 0 ) + 'px'; + } + } + else { + slide.style.top = ''; + } + + } + + if( oldScale !== scale ) { + dispatchEvent( 'resize', { + 'oldScale': oldScale, + 'scale': scale, + 'size': size + } ); + } + } + + updateProgress(); + updateParallax(); + + if( isOverview() ) { + updateOverview(); + } + + } + + } + + /** + * Applies layout logic to the contents of all slides in + * the presentation. + * + * @param {string|number} width + * @param {string|number} height + */ + function layoutSlideContents( width, height ) { + + // Handle sizing of elements with the 'stretch' class + toArray( dom.slides.querySelectorAll( 'section > .stretch' ) ).forEach( function( element ) { + + // Determine how much vertical space we can use + var remainingHeight = getRemainingHeight( element, height ); + + // Consider the aspect ratio of media elements + if( /(img|video)/gi.test( element.nodeName ) ) { + var nw = element.naturalWidth || element.videoWidth, + nh = element.naturalHeight || element.videoHeight; + + var es = Math.min( width / nw, remainingHeight / nh ); + + element.style.width = ( nw * es ) + 'px'; + element.style.height = ( nh * es ) + 'px'; + + } + else { + element.style.width = width + 'px'; + element.style.height = remainingHeight + 'px'; + } + + } ); + + } + + /** + * Calculates the computed pixel size of our slides. These + * values are based on the width and height configuration + * options. + * + * @param {number} [presentationWidth=dom.wrapper.offsetWidth] + * @param {number} [presentationHeight=dom.wrapper.offsetHeight] + */ + function getComputedSlideSize( presentationWidth, presentationHeight ) { + + var size = { + // Slide size + width: config.width, + height: config.height, + + // Presentation size + presentationWidth: presentationWidth || dom.wrapper.offsetWidth, + presentationHeight: presentationHeight || dom.wrapper.offsetHeight + }; + + // Reduce available space by margin + size.presentationWidth -= ( size.presentationWidth * config.margin ); + size.presentationHeight -= ( size.presentationHeight * config.margin ); + + // Slide width may be a percentage of available width + if( typeof size.width === 'string' && /%$/.test( size.width ) ) { + size.width = parseInt( size.width, 10 ) / 100 * size.presentationWidth; + } + + // Slide height may be a percentage of available height + if( typeof size.height === 'string' && /%$/.test( size.height ) ) { + size.height = parseInt( size.height, 10 ) / 100 * size.presentationHeight; + } + + return size; + + } + + /** + * Stores the vertical index of a stack so that the same + * vertical slide can be selected when navigating to and + * from the stack. + * + * @param {HTMLElement} stack The vertical stack element + * @param {string|number} [v=0] Index to memorize + */ + function setPreviousVerticalIndex( stack, v ) { + + if( typeof stack === 'object' && typeof stack.setAttribute === 'function' ) { + stack.setAttribute( 'data-previous-indexv', v || 0 ); + } + + } + + /** + * Retrieves the vertical index which was stored using + * #setPreviousVerticalIndex() or 0 if no previous index + * exists. + * + * @param {HTMLElement} stack The vertical stack element + */ + function getPreviousVerticalIndex( stack ) { + + if( typeof stack === 'object' && typeof stack.setAttribute === 'function' && stack.classList.contains( 'stack' ) ) { + // Prefer manually defined start-indexv + var attributeName = stack.hasAttribute( 'data-start-indexv' ) ? 'data-start-indexv' : 'data-previous-indexv'; + + return parseInt( stack.getAttribute( attributeName ) || 0, 10 ); + } + + return 0; + + } + + /** + * Displays the overview of slides (quick nav) by scaling + * down and arranging all slide elements. + */ + function activateOverview() { + + // Only proceed if enabled in config + if( config.overview && !isOverview() ) { + + overview = true; + + dom.wrapper.classList.add( 'overview' ); + dom.wrapper.classList.remove( 'overview-deactivating' ); + + if( features.overviewTransitions ) { + setTimeout( function() { + dom.wrapper.classList.add( 'overview-animated' ); + }, 1 ); + } + + // Don't auto-slide while in overview mode + cancelAutoSlide(); + + // Move the backgrounds element into the slide container to + // that the same scaling is applied + dom.slides.appendChild( dom.background ); + + // Clicking on an overview slide navigates to it + toArray( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) ).forEach( function( slide ) { + if( !slide.classList.contains( 'stack' ) ) { + slide.addEventListener( 'click', onOverviewSlideClicked, true ); + } + } ); + + // Calculate slide sizes + var margin = 70; + var slideSize = getComputedSlideSize(); + overviewSlideWidth = slideSize.width + margin; + overviewSlideHeight = slideSize.height + margin; + + // Reverse in RTL mode + if( config.rtl ) { + overviewSlideWidth = -overviewSlideWidth; + } + + updateSlidesVisibility(); + layoutOverview(); + updateOverview(); + + layout(); + + // Notify observers of the overview showing + dispatchEvent( 'overviewshown', { + 'indexh': indexh, + 'indexv': indexv, + 'currentSlide': currentSlide + } ); + + } + + } + + /** + * Uses CSS transforms to position all slides in a grid for + * display inside of the overview mode. + */ + function layoutOverview() { + + // Layout slides + toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ).forEach( function( hslide, h ) { + hslide.setAttribute( 'data-index-h', h ); + transformElement( hslide, 'translate3d(' + ( h * overviewSlideWidth ) + 'px, 0, 0)' ); + + if( hslide.classList.contains( 'stack' ) ) { + + toArray( hslide.querySelectorAll( 'section' ) ).forEach( function( vslide, v ) { + vslide.setAttribute( 'data-index-h', h ); + vslide.setAttribute( 'data-index-v', v ); + + transformElement( vslide, 'translate3d(0, ' + ( v * overviewSlideHeight ) + 'px, 0)' ); + } ); + + } + } ); + + // Layout slide backgrounds + toArray( dom.background.childNodes ).forEach( function( hbackground, h ) { + transformElement( hbackground, 'translate3d(' + ( h * overviewSlideWidth ) + 'px, 0, 0)' ); + + toArray( hbackground.querySelectorAll( '.slide-background' ) ).forEach( function( vbackground, v ) { + transformElement( vbackground, 'translate3d(0, ' + ( v * overviewSlideHeight ) + 'px, 0)' ); + } ); + } ); + + } + + /** + * Moves the overview viewport to the current slides. + * Called each time the current slide changes. + */ + function updateOverview() { + + var vmin = Math.min( window.innerWidth, window.innerHeight ); + var scale = Math.max( vmin / 5, 150 ) / vmin; + + transformSlides( { + overview: [ + 'scale('+ scale +')', + 'translateX('+ ( -indexh * overviewSlideWidth ) +'px)', + 'translateY('+ ( -indexv * overviewSlideHeight ) +'px)' + ].join( ' ' ) + } ); + + } + + /** + * Exits the slide overview and enters the currently + * active slide. + */ + function deactivateOverview() { + + // Only proceed if enabled in config + if( config.overview ) { + + overview = false; + + dom.wrapper.classList.remove( 'overview' ); + dom.wrapper.classList.remove( 'overview-animated' ); + + // Temporarily add a class so that transitions can do different things + // depending on whether they are exiting/entering overview, or just + // moving from slide to slide + dom.wrapper.classList.add( 'overview-deactivating' ); + + setTimeout( function () { + dom.wrapper.classList.remove( 'overview-deactivating' ); + }, 1 ); + + // Move the background element back out + dom.wrapper.appendChild( dom.background ); + + // Clean up changes made to slides + toArray( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) ).forEach( function( slide ) { + transformElement( slide, '' ); + + slide.removeEventListener( 'click', onOverviewSlideClicked, true ); + } ); + + // Clean up changes made to backgrounds + toArray( dom.background.querySelectorAll( '.slide-background' ) ).forEach( function( background ) { + transformElement( background, '' ); + } ); + + transformSlides( { overview: '' } ); + + slide( indexh, indexv ); + + layout(); + + cueAutoSlide(); + + // Notify observers of the overview hiding + dispatchEvent( 'overviewhidden', { + 'indexh': indexh, + 'indexv': indexv, + 'currentSlide': currentSlide + } ); + + } + } + + /** + * Toggles the slide overview mode on and off. + * + * @param {Boolean} [override] Flag which overrides the + * toggle logic and forcibly sets the desired state. True means + * overview is open, false means it's closed. + */ + function toggleOverview( override ) { + + if( typeof override === 'boolean' ) { + override ? activateOverview() : deactivateOverview(); + } + else { + isOverview() ? deactivateOverview() : activateOverview(); + } + + } + + /** + * Checks if the overview is currently active. + * + * @return {Boolean} true if the overview is active, + * false otherwise + */ + function isOverview() { + + return overview; + + } + + /** + * Return a hash URL that will resolve to the current slide location. + */ + function locationHash() { + + var url = '/'; + + // Attempt to create a named link based on the slide's ID + var id = currentSlide ? currentSlide.getAttribute( 'id' ) : null; + if( id ) { + id = encodeURIComponent( id ); + } + + var indexf; + if( config.fragmentInURL ) { + indexf = getIndices().f; + } + + // If the current slide has an ID, use that as a named link, + // but we don't support named links with a fragment index + if( typeof id === 'string' && id.length && indexf === undefined ) { + url = '/' + id; + } + // Otherwise use the /h/v index + else { + var hashIndexBase = config.hashOneBasedIndex ? 1 : 0; + if( indexh > 0 || indexv > 0 || indexf !== undefined ) url += indexh + hashIndexBase; + if( indexv > 0 || indexf !== undefined ) url += '/' + (indexv + hashIndexBase ); + if( indexf !== undefined ) url += '/' + indexf; + } + + return url; + + } + + /** + * Checks if the current or specified slide is vertical + * (nested within another slide). + * + * @param {HTMLElement} [slide=currentSlide] The slide to check + * orientation of + * @return {Boolean} + */ + function isVerticalSlide( slide ) { + + // Prefer slide argument, otherwise use current slide + slide = slide ? slide : currentSlide; + + return slide && slide.parentNode && !!slide.parentNode.nodeName.match( /section/i ); + + } + + /** + * Handling the fullscreen functionality via the fullscreen API + * + * @see http://fullscreen.spec.whatwg.org/ + * @see https://developer.mozilla.org/en-US/docs/DOM/Using_fullscreen_mode + */ + function enterFullscreen() { + + var element = document.documentElement; + + // Check which implementation is available + var requestMethod = element.requestFullscreen || + element.webkitRequestFullscreen || + element.webkitRequestFullScreen || + element.mozRequestFullScreen || + element.msRequestFullscreen; + + if( requestMethod ) { + requestMethod.apply( element ); + } + + } + + /** + * Shows the mouse pointer after it has been hidden with + * #hideCursor. + */ + function showCursor() { + + if( cursorHidden ) { + cursorHidden = false; + dom.wrapper.style.cursor = ''; + } + + } + + /** + * Hides the mouse pointer when it's on top of the .reveal + * container. + */ + function hideCursor() { + + if( cursorHidden === false ) { + cursorHidden = true; + dom.wrapper.style.cursor = 'none'; + } + + } + + /** + * Enters the paused mode which fades everything on screen to + * black. + */ + function pause() { + + if( config.pause ) { + var wasPaused = dom.wrapper.classList.contains( 'paused' ); + + cancelAutoSlide(); + dom.wrapper.classList.add( 'paused' ); + + if( wasPaused === false ) { + dispatchEvent( 'paused' ); + } + } + + } + + /** + * Exits from the paused mode. + */ + function resume() { + + var wasPaused = dom.wrapper.classList.contains( 'paused' ); + dom.wrapper.classList.remove( 'paused' ); + + cueAutoSlide(); + + if( wasPaused ) { + dispatchEvent( 'resumed' ); + } + + } + + /** + * Toggles the paused mode on and off. + */ + function togglePause( override ) { + + if( typeof override === 'boolean' ) { + override ? pause() : resume(); + } + else { + isPaused() ? resume() : pause(); + } + + } + + /** + * Checks if we are currently in the paused mode. + * + * @return {Boolean} + */ + function isPaused() { + + return dom.wrapper.classList.contains( 'paused' ); + + } + + /** + * Toggles the auto slide mode on and off. + * + * @param {Boolean} [override] Flag which sets the desired state. + * True means autoplay starts, false means it stops. + */ + + function toggleAutoSlide( override ) { + + if( typeof override === 'boolean' ) { + override ? resumeAutoSlide() : pauseAutoSlide(); + } + + else { + autoSlidePaused ? resumeAutoSlide() : pauseAutoSlide(); + } + + } + + /** + * Checks if the auto slide mode is currently on. + * + * @return {Boolean} + */ + function isAutoSliding() { + + return !!( autoSlide && !autoSlidePaused ); + + } + + /** + * Steps from the current point in the presentation to the + * slide which matches the specified horizontal and vertical + * indices. + * + * @param {number} [h=indexh] Horizontal index of the target slide + * @param {number} [v=indexv] Vertical index of the target slide + * @param {number} [f] Index of a fragment within the + * target slide to activate + * @param {number} [o] Origin for use in multimaster environments + */ + function slide( h, v, f, o ) { + + // Remember where we were at before + previousSlide = currentSlide; + + // Query all horizontal slides in the deck + var horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ); + + // Abort if there are no slides + if( horizontalSlides.length === 0 ) return; + + // If no vertical index is specified and the upcoming slide is a + // stack, resume at its previous vertical index + if( v === undefined && !isOverview() ) { + v = getPreviousVerticalIndex( horizontalSlides[ h ] ); + } + + // If we were on a vertical stack, remember what vertical index + // it was on so we can resume at the same position when returning + if( previousSlide && previousSlide.parentNode && previousSlide.parentNode.classList.contains( 'stack' ) ) { + setPreviousVerticalIndex( previousSlide.parentNode, indexv ); + } + + // Remember the state before this slide + var stateBefore = state.concat(); + + // Reset the state array + state.length = 0; + + var indexhBefore = indexh || 0, + indexvBefore = indexv || 0; + + // Activate and transition to the new slide + indexh = updateSlides( HORIZONTAL_SLIDES_SELECTOR, h === undefined ? indexh : h ); + indexv = updateSlides( VERTICAL_SLIDES_SELECTOR, v === undefined ? indexv : v ); + + // Update the visibility of slides now that the indices have changed + updateSlidesVisibility(); + + layout(); + + // Update the overview if it's currently active + if( isOverview() ) { + updateOverview(); + } + + // Find the current horizontal slide and any possible vertical slides + // within it + var currentHorizontalSlide = horizontalSlides[ indexh ], + currentVerticalSlides = currentHorizontalSlide.querySelectorAll( 'section' ); + + // Store references to the previous and current slides + currentSlide = currentVerticalSlides[ indexv ] || currentHorizontalSlide; + + // Show fragment, if specified + if( typeof f !== 'undefined' ) { + navigateFragment( f ); + } + + // Dispatch an event if the slide changed + var slideChanged = ( indexh !== indexhBefore || indexv !== indexvBefore ); + if (!slideChanged) { + // Ensure that the previous slide is never the same as the current + previousSlide = null; + } + + // Solves an edge case where the previous slide maintains the + // 'present' class when navigating between adjacent vertical + // stacks + if( previousSlide && previousSlide !== currentSlide ) { + previousSlide.classList.remove( 'present' ); + previousSlide.setAttribute( 'aria-hidden', 'true' ); + + // Reset all slides upon navigate to home + // Issue: #285 + if ( dom.wrapper.querySelector( HOME_SLIDE_SELECTOR ).classList.contains( 'present' ) ) { + // Launch async task + setTimeout( function () { + var slides = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR + '.stack') ), i; + for( i in slides ) { + if( slides[i] ) { + // Reset stack + setPreviousVerticalIndex( slides[i], 0 ); + } + } + }, 0 ); + } + } + + // Apply the new state + stateLoop: for( var i = 0, len = state.length; i < len; i++ ) { + // Check if this state existed on the previous slide. If it + // did, we will avoid adding it repeatedly + for( var j = 0; j < stateBefore.length; j++ ) { + if( stateBefore[j] === state[i] ) { + stateBefore.splice( j, 1 ); + continue stateLoop; + } + } + + document.documentElement.classList.add( state[i] ); + + // Dispatch custom event matching the state's name + dispatchEvent( state[i] ); + } + + // Clean up the remains of the previous state + while( stateBefore.length ) { + document.documentElement.classList.remove( stateBefore.pop() ); + } + + if( slideChanged ) { + dispatchEvent( 'slidechanged', { + 'indexh': indexh, + 'indexv': indexv, + 'previousSlide': previousSlide, + 'currentSlide': currentSlide, + 'origin': o + } ); + } + + // Handle embedded content + if( slideChanged || !previousSlide ) { + stopEmbeddedContent( previousSlide ); + startEmbeddedContent( currentSlide ); + } + + // Announce the current slide contents, for screen readers + dom.statusDiv.textContent = getStatusText( currentSlide ); + + updateControls(); + updateProgress(); + updateBackground(); + updateParallax(); + updateSlideNumber(); + updateNotes(); + updateFragments(); + + // Update the URL hash + writeURL(); + + cueAutoSlide(); + + } + + /** + * Syncs the presentation with the current DOM. Useful + * when new slides or control elements are added or when + * the configuration has changed. + */ + function sync() { + + // Subscribe to input + removeEventListeners(); + addEventListeners(); + + // Force a layout to make sure the current config is accounted for + layout(); + + // Reflect the current autoSlide value + autoSlide = config.autoSlide; + + // Start auto-sliding if it's enabled + cueAutoSlide(); + + // Re-create the slide backgrounds + createBackgrounds(); + + // Write the current hash to the URL + writeURL(); + + sortAllFragments(); + + updateControls(); + updateProgress(); + updateSlideNumber(); + updateSlidesVisibility(); + updateBackground( true ); + updateNotesVisibility(); + updateNotes(); + + formatEmbeddedContent(); + + // Start or stop embedded content depending on global config + if( config.autoPlayMedia === false ) { + stopEmbeddedContent( currentSlide, { unloadIframes: false } ); + } + else { + startEmbeddedContent( currentSlide ); + } + + if( isOverview() ) { + layoutOverview(); + } + + } + + /** + * Updates reveal.js to keep in sync with new slide attributes. For + * example, if you add a new `data-background-image` you can call + * this to have reveal.js render the new background image. + * + * Similar to #sync() but more efficient when you only need to + * refresh a specific slide. + * + * @param {HTMLElement} slide + */ + function syncSlide( slide ) { + + // Default to the current slide + slide = slide || currentSlide; + + syncBackground( slide ); + syncFragments( slide ); + + updateBackground(); + updateNotes(); + + loadSlide( slide ); + + } + + /** + * Formats the fragments on the given slide so that they have + * valid indices. Call this if fragments are changed in the DOM + * after reveal.js has already initialized. + * + * @param {HTMLElement} slide + * @return {Array} a list of the HTML fragments that were synced + */ + function syncFragments( slide ) { + + // Default to the current slide + slide = slide || currentSlide; + + return sortFragments( slide.querySelectorAll( '.fragment' ) ); + + } + + /** + * Resets all vertical slides so that only the first + * is visible. + */ + function resetVerticalSlides() { + + var horizontalSlides = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ); + horizontalSlides.forEach( function( horizontalSlide ) { + + var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) ); + verticalSlides.forEach( function( verticalSlide, y ) { + + if( y > 0 ) { + verticalSlide.classList.remove( 'present' ); + verticalSlide.classList.remove( 'past' ); + verticalSlide.classList.add( 'future' ); + verticalSlide.setAttribute( 'aria-hidden', 'true' ); + } + + } ); + + } ); + + } + + /** + * Sorts and formats all of fragments in the + * presentation. + */ + function sortAllFragments() { + + var horizontalSlides = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ); + horizontalSlides.forEach( function( horizontalSlide ) { + + var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) ); + verticalSlides.forEach( function( verticalSlide, y ) { + + sortFragments( verticalSlide.querySelectorAll( '.fragment' ) ); + + } ); + + if( verticalSlides.length === 0 ) sortFragments( horizontalSlide.querySelectorAll( '.fragment' ) ); + + } ); + + } + + /** + * Randomly shuffles all slides in the deck. + */ + function shuffle() { + + var slides = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ); + + slides.forEach( function( slide ) { + + // Insert this slide next to another random slide. This may + // cause the slide to insert before itself but that's fine. + dom.slides.insertBefore( slide, slides[ Math.floor( Math.random() * slides.length ) ] ); + + } ); + + } + + /** + * Updates one dimension of slides by showing the slide + * with the specified index. + * + * @param {string} selector A CSS selector that will fetch + * the group of slides we are working with + * @param {number} index The index of the slide that should be + * shown + * + * @return {number} The index of the slide that is now shown, + * might differ from the passed in index if it was out of + * bounds. + */ + function updateSlides( selector, index ) { + + // Select all slides and convert the NodeList result to + // an array + var slides = toArray( dom.wrapper.querySelectorAll( selector ) ), + slidesLength = slides.length; + + var printMode = isPrintingPDF(); + + if( slidesLength ) { + + // Should the index loop? + if( config.loop ) { + index %= slidesLength; + + if( index < 0 ) { + index = slidesLength + index; + } + } + + // Enforce max and minimum index bounds + index = Math.max( Math.min( index, slidesLength - 1 ), 0 ); + + for( var i = 0; i < slidesLength; i++ ) { + var element = slides[i]; + + var reverse = config.rtl && !isVerticalSlide( element ); + + element.classList.remove( 'past' ); + element.classList.remove( 'present' ); + element.classList.remove( 'future' ); + + // http://www.w3.org/html/wg/drafts/html/master/editing.html#the-hidden-attribute + element.setAttribute( 'hidden', '' ); + element.setAttribute( 'aria-hidden', 'true' ); + + // If this element contains vertical slides + if( element.querySelector( 'section' ) ) { + element.classList.add( 'stack' ); + } + + // If we're printing static slides, all slides are "present" + if( printMode ) { + element.classList.add( 'present' ); + continue; + } + + if( i < index ) { + // Any element previous to index is given the 'past' class + element.classList.add( reverse ? 'future' : 'past' ); + + if( config.fragments ) { + // Show all fragments in prior slides + toArray( element.querySelectorAll( '.fragment' ) ).forEach( function( fragment ) { + fragment.classList.add( 'visible' ); + fragment.classList.remove( 'current-fragment' ); + } ); + } + } + else if( i > index ) { + // Any element subsequent to index is given the 'future' class + element.classList.add( reverse ? 'past' : 'future' ); + + if( config.fragments ) { + // Hide all fragments in future slides + toArray( element.querySelectorAll( '.fragment.visible' ) ).forEach( function( fragment ) { + fragment.classList.remove( 'visible' ); + fragment.classList.remove( 'current-fragment' ); + } ); + } + } + } + + // Mark the current slide as present + slides[index].classList.add( 'present' ); + slides[index].removeAttribute( 'hidden' ); + slides[index].removeAttribute( 'aria-hidden' ); + + // If this slide has a state associated with it, add it + // onto the current state of the deck + var slideState = slides[index].getAttribute( 'data-state' ); + if( slideState ) { + state = state.concat( slideState.split( ' ' ) ); + } + + } + else { + // Since there are no slides we can't be anywhere beyond the + // zeroth index + index = 0; + } + + return index; + + } + + /** + * Optimization method; hide all slides that are far away + * from the present slide. + */ + function updateSlidesVisibility() { + + // Select all slides and convert the NodeList result to + // an array + var horizontalSlides = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ), + horizontalSlidesLength = horizontalSlides.length, + distanceX, + distanceY; + + if( horizontalSlidesLength && typeof indexh !== 'undefined' ) { + + // The number of steps away from the present slide that will + // be visible + var viewDistance = isOverview() ? 10 : config.viewDistance; + + // Limit view distance on weaker devices + if( isMobileDevice ) { + viewDistance = isOverview() ? 6 : 2; + } + + // All slides need to be visible when exporting to PDF + if( isPrintingPDF() ) { + viewDistance = Number.MAX_VALUE; + } + + for( var x = 0; x < horizontalSlidesLength; x++ ) { + var horizontalSlide = horizontalSlides[x]; + + var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) ), + verticalSlidesLength = verticalSlides.length; + + // Determine how far away this slide is from the present + distanceX = Math.abs( ( indexh || 0 ) - x ) || 0; + + // If the presentation is looped, distance should measure + // 1 between the first and last slides + if( config.loop ) { + distanceX = Math.abs( ( ( indexh || 0 ) - x ) % ( horizontalSlidesLength - viewDistance ) ) || 0; + } + + // Show the horizontal slide if it's within the view distance + if( distanceX < viewDistance ) { + loadSlide( horizontalSlide ); + } + else { + unloadSlide( horizontalSlide ); + } + + if( verticalSlidesLength ) { + + var oy = getPreviousVerticalIndex( horizontalSlide ); + + for( var y = 0; y < verticalSlidesLength; y++ ) { + var verticalSlide = verticalSlides[y]; + + distanceY = x === ( indexh || 0 ) ? Math.abs( ( indexv || 0 ) - y ) : Math.abs( y - oy ); + + if( distanceX + distanceY < viewDistance ) { + loadSlide( verticalSlide ); + } + else { + unloadSlide( verticalSlide ); + } + } + + } + } + + // Flag if there are ANY vertical slides, anywhere in the deck + if( dom.wrapper.querySelectorAll( '.slides>section>section' ).length ) { + dom.wrapper.classList.add( 'has-vertical-slides' ); + } + else { + dom.wrapper.classList.remove( 'has-vertical-slides' ); + } + + // Flag if there are ANY horizontal slides, anywhere in the deck + if( dom.wrapper.querySelectorAll( '.slides>section' ).length > 1 ) { + dom.wrapper.classList.add( 'has-horizontal-slides' ); + } + else { + dom.wrapper.classList.remove( 'has-horizontal-slides' ); + } + + } + + } + + /** + * Pick up notes from the current slide and display them + * to the viewer. + * + * @see {@link config.showNotes} + */ + function updateNotes() { + + if( config.showNotes && dom.speakerNotes && currentSlide && !isPrintingPDF() ) { + + dom.speakerNotes.innerHTML = getSlideNotes() || 'No notes on this slide.'; + + } + + } + + /** + * Updates the visibility of the speaker notes sidebar that + * is used to share annotated slides. The notes sidebar is + * only visible if showNotes is true and there are notes on + * one or more slides in the deck. + */ + function updateNotesVisibility() { + + if( config.showNotes && hasNotes() ) { + dom.wrapper.classList.add( 'show-notes' ); + } + else { + dom.wrapper.classList.remove( 'show-notes' ); + } + + } + + /** + * Checks if there are speaker notes for ANY slide in the + * presentation. + */ + function hasNotes() { + + return dom.slides.querySelectorAll( '[data-notes], aside.notes' ).length > 0; + + } + + /** + * Updates the progress bar to reflect the current slide. + */ + function updateProgress() { + + // Update progress if enabled + if( config.progress && dom.progressbar ) { + + dom.progressbar.style.width = getProgress() * dom.wrapper.offsetWidth + 'px'; + + } + + } + + + /** + * Updates the slide number to match the current slide. + */ + function updateSlideNumber() { + + // Update slide number if enabled + if( config.slideNumber && dom.slideNumber ) { + + var value; + var format = 'h.v'; + + if( typeof config.slideNumber === 'function' ) { + value = config.slideNumber(); + } + else { + // Check if a custom number format is available + if( typeof config.slideNumber === 'string' ) { + format = config.slideNumber; + } + + // If there are ONLY vertical slides in this deck, always use + // a flattened slide number + if( !/c/.test( format ) && dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ).length === 1 ) { + format = 'c'; + } + + value = []; + switch( format ) { + case 'c': + value.push( getSlidePastCount() + 1 ); + break; + case 'c/t': + value.push( getSlidePastCount() + 1, '/', getTotalSlides() ); + break; + case 'h/v': + value.push( indexh + 1 ); + if( isVerticalSlide() ) value.push( '/', indexv + 1 ); + break; + default: + value.push( indexh + 1 ); + if( isVerticalSlide() ) value.push( '.', indexv + 1 ); + } + } + + dom.slideNumber.innerHTML = formatSlideNumber( value[0], value[1], value[2] ); + } + + } + + /** + * Applies HTML formatting to a slide number before it's + * written to the DOM. + * + * @param {number} a Current slide + * @param {string} delimiter Character to separate slide numbers + * @param {(number|*)} b Total slides + * @return {string} HTML string fragment + */ + function formatSlideNumber( a, delimiter, b ) { + + var url = '#' + locationHash(); + if( typeof b === 'number' && !isNaN( b ) ) { + return '' + + ''+ a +'' + + ''+ delimiter +'' + + ''+ b +'' + + ''; + } + else { + return '' + + ''+ a +'' + + ''; + } + + } + + /** + * Updates the state of all control/navigation arrows. + */ + function updateControls() { + + var routes = availableRoutes(); + var fragments = availableFragments(); + + // Remove the 'enabled' class from all directions + dom.controlsLeft.concat( dom.controlsRight ) + .concat( dom.controlsUp ) + .concat( dom.controlsDown ) + .concat( dom.controlsPrev ) + .concat( dom.controlsNext ).forEach( function( node ) { + node.classList.remove( 'enabled' ); + node.classList.remove( 'fragmented' ); + + // Set 'disabled' attribute on all directions + node.setAttribute( 'disabled', 'disabled' ); + } ); + + // Add the 'enabled' class to the available routes; remove 'disabled' attribute to enable buttons + if( routes.left ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } ); + if( routes.right ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } ); + if( routes.up ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } ); + if( routes.down ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } ); + + // Prev/next buttons + if( routes.left || routes.up ) dom.controlsPrev.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } ); + if( routes.right || routes.down ) dom.controlsNext.forEach( function( el ) { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } ); + + // Highlight fragment directions + if( currentSlide ) { + + // Always apply fragment decorator to prev/next buttons + if( fragments.prev ) dom.controlsPrev.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); + if( fragments.next ) dom.controlsNext.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); + + // Apply fragment decorators to directional buttons based on + // what slide axis they are in + if( isVerticalSlide( currentSlide ) ) { + if( fragments.prev ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); + if( fragments.next ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); + } + else { + if( fragments.prev ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); + if( fragments.next ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } ); + } + + } + + if( config.controlsTutorial ) { + + // Highlight control arrows with an animation to ensure + // that the viewer knows how to navigate + if( !hasNavigatedDown && routes.down ) { + dom.controlsDownArrow.classList.add( 'highlight' ); + } + else { + dom.controlsDownArrow.classList.remove( 'highlight' ); + + if( !hasNavigatedRight && routes.right && indexv === 0 ) { + dom.controlsRightArrow.classList.add( 'highlight' ); + } + else { + dom.controlsRightArrow.classList.remove( 'highlight' ); + } + } + + } + + } + + /** + * Updates the background elements to reflect the current + * slide. + * + * @param {boolean} includeAll If true, the backgrounds of + * all vertical slides (not just the present) will be updated. + */ + function updateBackground( includeAll ) { + + var currentBackground = null; + + // Reverse past/future classes when in RTL mode + var horizontalPast = config.rtl ? 'future' : 'past', + horizontalFuture = config.rtl ? 'past' : 'future'; + + // Update the classes of all backgrounds to match the + // states of their slides (past/present/future) + toArray( dom.background.childNodes ).forEach( function( backgroundh, h ) { + + backgroundh.classList.remove( 'past' ); + backgroundh.classList.remove( 'present' ); + backgroundh.classList.remove( 'future' ); + + if( h < indexh ) { + backgroundh.classList.add( horizontalPast ); + } + else if ( h > indexh ) { + backgroundh.classList.add( horizontalFuture ); + } + else { + backgroundh.classList.add( 'present' ); + + // Store a reference to the current background element + currentBackground = backgroundh; + } + + if( includeAll || h === indexh ) { + toArray( backgroundh.querySelectorAll( '.slide-background' ) ).forEach( function( backgroundv, v ) { + + backgroundv.classList.remove( 'past' ); + backgroundv.classList.remove( 'present' ); + backgroundv.classList.remove( 'future' ); + + if( v < indexv ) { + backgroundv.classList.add( 'past' ); + } + else if ( v > indexv ) { + backgroundv.classList.add( 'future' ); + } + else { + backgroundv.classList.add( 'present' ); + + // Only if this is the present horizontal and vertical slide + if( h === indexh ) currentBackground = backgroundv; + } + + } ); + } + + } ); + + // Stop content inside of previous backgrounds + if( previousBackground ) { + + stopEmbeddedContent( previousBackground ); + + } + + // Start content in the current background + if( currentBackground ) { + + startEmbeddedContent( currentBackground ); + + var currentBackgroundContent = currentBackground.querySelector( '.slide-background-content' ); + if( currentBackgroundContent ) { + + var backgroundImageURL = currentBackgroundContent.style.backgroundImage || ''; + + // Restart GIFs (doesn't work in Firefox) + if( /\.gif/i.test( backgroundImageURL ) ) { + currentBackgroundContent.style.backgroundImage = ''; + window.getComputedStyle( currentBackgroundContent ).opacity; + currentBackgroundContent.style.backgroundImage = backgroundImageURL; + } + + } + + // Don't transition between identical backgrounds. This + // prevents unwanted flicker. + var previousBackgroundHash = previousBackground ? previousBackground.getAttribute( 'data-background-hash' ) : null; + var currentBackgroundHash = currentBackground.getAttribute( 'data-background-hash' ); + if( currentBackgroundHash && currentBackgroundHash === previousBackgroundHash && currentBackground !== previousBackground ) { + dom.background.classList.add( 'no-transition' ); + } + + previousBackground = currentBackground; + + } + + // If there's a background brightness flag for this slide, + // bubble it to the .reveal container + if( currentSlide ) { + [ 'has-light-background', 'has-dark-background' ].forEach( function( classToBubble ) { + if( currentSlide.classList.contains( classToBubble ) ) { + dom.wrapper.classList.add( classToBubble ); + } + else { + dom.wrapper.classList.remove( classToBubble ); + } + } ); + } + + // Allow the first background to apply without transition + setTimeout( function() { + dom.background.classList.remove( 'no-transition' ); + }, 1 ); + + } + + /** + * Updates the position of the parallax background based + * on the current slide index. + */ + function updateParallax() { + + if( config.parallaxBackgroundImage ) { + + var horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ), + verticalSlides = dom.wrapper.querySelectorAll( VERTICAL_SLIDES_SELECTOR ); + + var backgroundSize = dom.background.style.backgroundSize.split( ' ' ), + backgroundWidth, backgroundHeight; + + if( backgroundSize.length === 1 ) { + backgroundWidth = backgroundHeight = parseInt( backgroundSize[0], 10 ); + } + else { + backgroundWidth = parseInt( backgroundSize[0], 10 ); + backgroundHeight = parseInt( backgroundSize[1], 10 ); + } + + var slideWidth = dom.background.offsetWidth, + horizontalSlideCount = horizontalSlides.length, + horizontalOffsetMultiplier, + horizontalOffset; + + if( typeof config.parallaxBackgroundHorizontal === 'number' ) { + horizontalOffsetMultiplier = config.parallaxBackgroundHorizontal; + } + else { + horizontalOffsetMultiplier = horizontalSlideCount > 1 ? ( backgroundWidth - slideWidth ) / ( horizontalSlideCount-1 ) : 0; + } + + horizontalOffset = horizontalOffsetMultiplier * indexh * -1; + + var slideHeight = dom.background.offsetHeight, + verticalSlideCount = verticalSlides.length, + verticalOffsetMultiplier, + verticalOffset; + + if( typeof config.parallaxBackgroundVertical === 'number' ) { + verticalOffsetMultiplier = config.parallaxBackgroundVertical; + } + else { + verticalOffsetMultiplier = ( backgroundHeight - slideHeight ) / ( verticalSlideCount-1 ); + } + + verticalOffset = verticalSlideCount > 0 ? verticalOffsetMultiplier * indexv : 0; + + dom.background.style.backgroundPosition = horizontalOffset + 'px ' + -verticalOffset + 'px'; + + } + + } + + /** + * Should the given element be preloaded? + * Decides based on local element attributes and global config. + * + * @param {HTMLElement} element + */ + function shouldPreload( element ) { + + // Prefer an explicit global preload setting + var preload = config.preloadIframes; + + // If no global setting is available, fall back on the element's + // own preload setting + if( typeof preload !== 'boolean' ) { + preload = element.hasAttribute( 'data-preload' ); + } + + return preload; + } + + /** + * Called when the given slide is within the configured view + * distance. Shows the slide element and loads any content + * that is set to load lazily (data-src). + * + * @param {HTMLElement} slide Slide to show + */ + function loadSlide( slide, options ) { + + options = options || {}; + + // Show the slide element + slide.style.display = config.display; + + // Media elements with data-src attributes + toArray( slide.querySelectorAll( 'img[data-src], video[data-src], audio[data-src], iframe[data-src]' ) ).forEach( function( element ) { + if( element.tagName !== 'IFRAME' || shouldPreload( element ) ) { + element.setAttribute( 'src', element.getAttribute( 'data-src' ) ); + element.setAttribute( 'data-lazy-loaded', '' ); + element.removeAttribute( 'data-src' ); + } + } ); + + // Media elements with children + toArray( slide.querySelectorAll( 'video, audio' ) ).forEach( function( media ) { + var sources = 0; + + toArray( media.querySelectorAll( 'source[data-src]' ) ).forEach( function( source ) { + source.setAttribute( 'src', source.getAttribute( 'data-src' ) ); + source.removeAttribute( 'data-src' ); + source.setAttribute( 'data-lazy-loaded', '' ); + sources += 1; + } ); + + // If we rewrote sources for this video/audio element, we need + // to manually tell it to load from its new origin + if( sources > 0 ) { + media.load(); + } + } ); + + + // Show the corresponding background element + var background = slide.slideBackgroundElement; + if( background ) { + background.style.display = 'block'; + + var backgroundContent = slide.slideBackgroundContentElement; + + // If the background contains media, load it + if( background.hasAttribute( 'data-loaded' ) === false ) { + background.setAttribute( 'data-loaded', 'true' ); + + var backgroundImage = slide.getAttribute( 'data-background-image' ), + backgroundVideo = slide.getAttribute( 'data-background-video' ), + backgroundVideoLoop = slide.hasAttribute( 'data-background-video-loop' ), + backgroundVideoMuted = slide.hasAttribute( 'data-background-video-muted' ), + backgroundIframe = slide.getAttribute( 'data-background-iframe' ); + + // Images + if( backgroundImage ) { + backgroundContent.style.backgroundImage = 'url('+ encodeURI( backgroundImage ) +')'; + } + // Videos + else if ( backgroundVideo && !isSpeakerNotes() ) { + var video = document.createElement( 'video' ); + + if( backgroundVideoLoop ) { + video.setAttribute( 'loop', '' ); + } + + if( backgroundVideoMuted ) { + video.muted = true; + } + + // Inline video playback works (at least in Mobile Safari) as + // long as the video is muted and the `playsinline` attribute is + // present + if( isMobileDevice ) { + video.muted = true; + video.autoplay = true; + video.setAttribute( 'playsinline', '' ); + } + + // Support comma separated lists of video sources + backgroundVideo.split( ',' ).forEach( function( source ) { + video.innerHTML += ''; + } ); + + backgroundContent.appendChild( video ); + } + // Iframes + else if( backgroundIframe && options.excludeIframes !== true ) { + var iframe = document.createElement( 'iframe' ); + iframe.setAttribute( 'allowfullscreen', '' ); + iframe.setAttribute( 'mozallowfullscreen', '' ); + iframe.setAttribute( 'webkitallowfullscreen', '' ); + + // Only load autoplaying content when the slide is shown to + // avoid having it play in the background + if( /autoplay=(1|true|yes)/gi.test( backgroundIframe ) ) { + iframe.setAttribute( 'data-src', backgroundIframe ); + } + else { + iframe.setAttribute( 'src', backgroundIframe ); + } + + iframe.style.width = '100%'; + iframe.style.height = '100%'; + iframe.style.maxHeight = '100%'; + iframe.style.maxWidth = '100%'; + + backgroundContent.appendChild( iframe ); + } + } + + } + + } + + /** + * Unloads and hides the given slide. This is called when the + * slide is moved outside of the configured view distance. + * + * @param {HTMLElement} slide + */ + function unloadSlide( slide ) { + + // Hide the slide element + slide.style.display = 'none'; + + // Hide the corresponding background element + var background = getSlideBackground( slide ); + if( background ) { + background.style.display = 'none'; + } + + // Reset lazy-loaded media elements with src attributes + toArray( slide.querySelectorAll( 'video[data-lazy-loaded][src], audio[data-lazy-loaded][src], iframe[data-lazy-loaded][src]' ) ).forEach( function( element ) { + element.setAttribute( 'data-src', element.getAttribute( 'src' ) ); + element.removeAttribute( 'src' ); + } ); + + // Reset lazy-loaded media elements with children + toArray( slide.querySelectorAll( 'video[data-lazy-loaded] source[src], audio source[src]' ) ).forEach( function( source ) { + source.setAttribute( 'data-src', source.getAttribute( 'src' ) ); + source.removeAttribute( 'src' ); + } ); + + } + + /** + * Determine what available routes there are for navigation. + * + * @return {{left: boolean, right: boolean, up: boolean, down: boolean}} + */ + function availableRoutes() { + + var horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ), + verticalSlides = dom.wrapper.querySelectorAll( VERTICAL_SLIDES_SELECTOR ); + + var routes = { + left: indexh > 0, + right: indexh < horizontalSlides.length - 1, + up: indexv > 0, + down: indexv < verticalSlides.length - 1 + }; + + // Looped presentations can always be navigated as long as + // there are slides available + if( config.loop ) { + if( horizontalSlides.length > 1 ) { + routes.left = true; + routes.right = true; + } + + if( verticalSlides.length > 1 ) { + routes.up = true; + routes.down = true; + } + } + + // Reverse horizontal controls for rtl + if( config.rtl ) { + var left = routes.left; + routes.left = routes.right; + routes.right = left; + } + + return routes; + + } + + /** + * Returns an object describing the available fragment + * directions. + * + * @return {{prev: boolean, next: boolean}} + */ + function availableFragments() { + + if( currentSlide && config.fragments ) { + var fragments = currentSlide.querySelectorAll( '.fragment' ); + var hiddenFragments = currentSlide.querySelectorAll( '.fragment:not(.visible)' ); + + return { + prev: fragments.length - hiddenFragments.length > 0, + next: !!hiddenFragments.length + }; + } + else { + return { prev: false, next: false }; + } + + } + + /** + * Enforces origin-specific format rules for embedded media. + */ + function formatEmbeddedContent() { + + var _appendParamToIframeSource = function( sourceAttribute, sourceURL, param ) { + toArray( dom.slides.querySelectorAll( 'iframe['+ sourceAttribute +'*="'+ sourceURL +'"]' ) ).forEach( function( el ) { + var src = el.getAttribute( sourceAttribute ); + if( src && src.indexOf( param ) === -1 ) { + el.setAttribute( sourceAttribute, src + ( !/\?/.test( src ) ? '?' : '&' ) + param ); + } + }); + }; + + // YouTube frames must include "?enablejsapi=1" + _appendParamToIframeSource( 'src', 'youtube.com/embed/', 'enablejsapi=1' ); + _appendParamToIframeSource( 'data-src', 'youtube.com/embed/', 'enablejsapi=1' ); + + // Vimeo frames must include "?api=1" + _appendParamToIframeSource( 'src', 'player.vimeo.com/', 'api=1' ); + _appendParamToIframeSource( 'data-src', 'player.vimeo.com/', 'api=1' ); + + } + + /** + * Start playback of any embedded content inside of + * the given element. + * + * @param {HTMLElement} element + */ + function startEmbeddedContent( element ) { + + if( element && !isSpeakerNotes() ) { + + // Restart GIFs + toArray( element.querySelectorAll( 'img[src$=".gif"]' ) ).forEach( function( el ) { + // Setting the same unchanged source like this was confirmed + // to work in Chrome, FF & Safari + el.setAttribute( 'src', el.getAttribute( 'src' ) ); + } ); + + // HTML5 media elements + toArray( element.querySelectorAll( 'video, audio' ) ).forEach( function( el ) { + if( closestParent( el, '.fragment' ) && !closestParent( el, '.fragment.visible' ) ) { + return; + } + + // Prefer an explicit global autoplay setting + var autoplay = config.autoPlayMedia; + + // If no global setting is available, fall back on the element's + // own autoplay setting + if( typeof autoplay !== 'boolean' ) { + autoplay = el.hasAttribute( 'data-autoplay' ) || !!closestParent( el, '.slide-background' ); + } + + if( autoplay && typeof el.play === 'function' ) { + + // If the media is ready, start playback + if( el.readyState > 1 ) { + startEmbeddedMedia( { target: el } ); + } + // Mobile devices never fire a loaded event so instead + // of waiting, we initiate playback + else if( isMobileDevice ) { + var promise = el.play(); + + // If autoplay does not work, ensure that the controls are visible so + // that the viewer can start the media on their own + if( promise && typeof promise.catch === 'function' && el.controls === false ) { + promise.catch( function() { + el.controls = true; + + // Once the video does start playing, hide the controls again + el.addEventListener( 'play', function() { + el.controls = false; + } ); + } ); + } + } + // If the media isn't loaded, wait before playing + else { + el.removeEventListener( 'loadeddata', startEmbeddedMedia ); // remove first to avoid dupes + el.addEventListener( 'loadeddata', startEmbeddedMedia ); + } + + } + } ); + + // Normal iframes + toArray( element.querySelectorAll( 'iframe[src]' ) ).forEach( function( el ) { + if( closestParent( el, '.fragment' ) && !closestParent( el, '.fragment.visible' ) ) { + return; + } + + startEmbeddedIframe( { target: el } ); + } ); + + // Lazy loading iframes + toArray( element.querySelectorAll( 'iframe[data-src]' ) ).forEach( function( el ) { + if( closestParent( el, '.fragment' ) && !closestParent( el, '.fragment.visible' ) ) { + return; + } + + if( el.getAttribute( 'src' ) !== el.getAttribute( 'data-src' ) ) { + el.removeEventListener( 'load', startEmbeddedIframe ); // remove first to avoid dupes + el.addEventListener( 'load', startEmbeddedIframe ); + el.setAttribute( 'src', el.getAttribute( 'data-src' ) ); + } + } ); + + } + + } + + /** + * Starts playing an embedded video/audio element after + * it has finished loading. + * + * @param {object} event + */ + function startEmbeddedMedia( event ) { + + var isAttachedToDOM = !!closestParent( event.target, 'html' ), + isVisible = !!closestParent( event.target, '.present' ); + + if( isAttachedToDOM && isVisible ) { + event.target.currentTime = 0; + event.target.play(); + } + + event.target.removeEventListener( 'loadeddata', startEmbeddedMedia ); + + } + + /** + * "Starts" the content of an embedded iframe using the + * postMessage API. + * + * @param {object} event + */ + function startEmbeddedIframe( event ) { + + var iframe = event.target; + + if( iframe && iframe.contentWindow ) { + + var isAttachedToDOM = !!closestParent( event.target, 'html' ), + isVisible = !!closestParent( event.target, '.present' ); + + if( isAttachedToDOM && isVisible ) { + + // Prefer an explicit global autoplay setting + var autoplay = config.autoPlayMedia; + + // If no global setting is available, fall back on the element's + // own autoplay setting + if( typeof autoplay !== 'boolean' ) { + autoplay = iframe.hasAttribute( 'data-autoplay' ) || !!closestParent( iframe, '.slide-background' ); + } + + // YouTube postMessage API + if( /youtube\.com\/embed\//.test( iframe.getAttribute( 'src' ) ) && autoplay ) { + iframe.contentWindow.postMessage( '{"event":"command","func":"playVideo","args":""}', '*' ); + } + // Vimeo postMessage API + else if( /player\.vimeo\.com\//.test( iframe.getAttribute( 'src' ) ) && autoplay ) { + iframe.contentWindow.postMessage( '{"method":"play"}', '*' ); + } + // Generic postMessage API + else { + iframe.contentWindow.postMessage( 'slide:start', '*' ); + } + + } + + } + + } + + /** + * Stop playback of any embedded content inside of + * the targeted slide. + * + * @param {HTMLElement} element + */ + function stopEmbeddedContent( element, options ) { + + options = extend( { + // Defaults + unloadIframes: true + }, options || {} ); + + if( element && element.parentNode ) { + // HTML5 media elements + toArray( element.querySelectorAll( 'video, audio' ) ).forEach( function( el ) { + if( !el.hasAttribute( 'data-ignore' ) && typeof el.pause === 'function' ) { + el.setAttribute('data-paused-by-reveal', ''); + el.pause(); + } + } ); + + // Generic postMessage API for non-lazy loaded iframes + toArray( element.querySelectorAll( 'iframe' ) ).forEach( function( el ) { + if( el.contentWindow ) el.contentWindow.postMessage( 'slide:stop', '*' ); + el.removeEventListener( 'load', startEmbeddedIframe ); + }); + + // YouTube postMessage API + toArray( element.querySelectorAll( 'iframe[src*="youtube.com/embed/"]' ) ).forEach( function( el ) { + if( !el.hasAttribute( 'data-ignore' ) && el.contentWindow && typeof el.contentWindow.postMessage === 'function' ) { + el.contentWindow.postMessage( '{"event":"command","func":"pauseVideo","args":""}', '*' ); + } + }); + + // Vimeo postMessage API + toArray( element.querySelectorAll( 'iframe[src*="player.vimeo.com/"]' ) ).forEach( function( el ) { + if( !el.hasAttribute( 'data-ignore' ) && el.contentWindow && typeof el.contentWindow.postMessage === 'function' ) { + el.contentWindow.postMessage( '{"method":"pause"}', '*' ); + } + }); + + if( options.unloadIframes === true ) { + // Unload lazy-loaded iframes + toArray( element.querySelectorAll( 'iframe[data-src]' ) ).forEach( function( el ) { + // Only removing the src doesn't actually unload the frame + // in all browsers (Firefox) so we set it to blank first + el.setAttribute( 'src', 'about:blank' ); + el.removeAttribute( 'src' ); + } ); + } + } + + } + + /** + * Returns the number of past slides. This can be used as a global + * flattened index for slides. + * + * @return {number} Past slide count + */ + function getSlidePastCount() { + + var horizontalSlides = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ); + + // The number of past slides + var pastCount = 0; + + // Step through all slides and count the past ones + mainLoop: for( var i = 0; i < horizontalSlides.length; i++ ) { + + var horizontalSlide = horizontalSlides[i]; + var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) ); + + for( var j = 0; j < verticalSlides.length; j++ ) { + + // Stop as soon as we arrive at the present + if( verticalSlides[j].classList.contains( 'present' ) ) { + break mainLoop; + } + + pastCount++; + + } + + // Stop as soon as we arrive at the present + if( horizontalSlide.classList.contains( 'present' ) ) { + break; + } + + // Don't count the wrapping section for vertical slides + if( horizontalSlide.classList.contains( 'stack' ) === false ) { + pastCount++; + } + + } + + return pastCount; + + } + + /** + * Returns a value ranging from 0-1 that represents + * how far into the presentation we have navigated. + * + * @return {number} + */ + function getProgress() { + + // The number of past and total slides + var totalCount = getTotalSlides(); + var pastCount = getSlidePastCount(); + + if( currentSlide ) { + + var allFragments = currentSlide.querySelectorAll( '.fragment' ); + + // If there are fragments in the current slide those should be + // accounted for in the progress. + if( allFragments.length > 0 ) { + var visibleFragments = currentSlide.querySelectorAll( '.fragment.visible' ); + + // This value represents how big a portion of the slide progress + // that is made up by its fragments (0-1) + var fragmentWeight = 0.9; + + // Add fragment progress to the past slide count + pastCount += ( visibleFragments.length / allFragments.length ) * fragmentWeight; + } + + } + + return Math.min( pastCount / ( totalCount - 1 ), 1 ); + + } + + /** + * Checks if this presentation is running inside of the + * speaker notes window. + * + * @return {boolean} + */ + function isSpeakerNotes() { + + return !!window.location.search.match( /receiver/gi ); + + } + + /** + * Reads the current URL (hash) and navigates accordingly. + */ + function readURL() { + + var hash = window.location.hash; + + // Attempt to parse the hash as either an index or name + var bits = hash.slice( 2 ).split( '/' ), + name = hash.replace( /#|\//gi, '' ); + + // If the first bit is not fully numeric and there is a name we + // can assume that this is a named link + if( !/^[0-9]*$/.test( bits[0] ) && name.length ) { + var element; + + // Ensure the named link is a valid HTML ID attribute + try { + element = document.getElementById( decodeURIComponent( name ) ); + } + catch ( error ) { } + + // Ensure that we're not already on a slide with the same name + var isSameNameAsCurrentSlide = currentSlide ? currentSlide.getAttribute( 'id' ) === name : false; + + if( element ) { + // If the slide exists and is not the current slide... + if ( !isSameNameAsCurrentSlide ) { + // ...find the position of the named slide and navigate to it + var indices = Reveal.getIndices(element); + slide(indices.h, indices.v); + } + } + // If the slide doesn't exist, navigate to the current slide + else { + slide( indexh || 0, indexv || 0 ); + } + } + else { + var hashIndexBase = config.hashOneBasedIndex ? 1 : 0; + + // Read the index components of the hash + var h = ( parseInt( bits[0], 10 ) - hashIndexBase ) || 0, + v = ( parseInt( bits[1], 10 ) - hashIndexBase ) || 0, + f; + + if( config.fragmentInURL ) { + f = parseInt( bits[2], 10 ); + if( isNaN( f ) ) { + f = undefined; + } + } + + if( h !== indexh || v !== indexv || f !== undefined ) { + slide( h, v, f ); + } + } + + } + + /** + * Updates the page URL (hash) to reflect the current + * state. + * + * @param {number} delay The time in ms to wait before + * writing the hash + */ + function writeURL( delay ) { + + // Make sure there's never more than one timeout running + clearTimeout( writeURLTimeout ); + + // If a delay is specified, timeout this call + if( typeof delay === 'number' ) { + writeURLTimeout = setTimeout( writeURL, delay ); + } + else if( currentSlide ) { + // If we're configured to push to history OR the history + // API is not avaialble. + if( config.history || !window.history ) { + window.location.hash = locationHash(); + } + // If we're configured to reflect the current slide in the + // URL without pushing to history. + else if( config.hash ) { + window.history.replaceState( null, null, '#' + locationHash() ); + } + // If history and hash are both disabled, a hash may still + // be added to the URL by clicking on a href with a hash + // target. Counter this by always removing the hash. + else { + window.history.replaceState( null, null, window.location.pathname + window.location.search ); + } + } + + } + /** + * Retrieves the h/v location and fragment of the current, + * or specified, slide. + * + * @param {HTMLElement} [slide] If specified, the returned + * index will be for this slide rather than the currently + * active one + * + * @return {{h: number, v: number, f: number}} + */ + function getIndices( slide ) { + + // By default, return the current indices + var h = indexh, + v = indexv, + f; + + // If a slide is specified, return the indices of that slide + if( slide ) { + var isVertical = isVerticalSlide( slide ); + var slideh = isVertical ? slide.parentNode : slide; + + // Select all horizontal slides + var horizontalSlides = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ); + + // Now that we know which the horizontal slide is, get its index + h = Math.max( horizontalSlides.indexOf( slideh ), 0 ); + + // Assume we're not vertical + v = undefined; + + // If this is a vertical slide, grab the vertical index + if( isVertical ) { + v = Math.max( toArray( slide.parentNode.querySelectorAll( 'section' ) ).indexOf( slide ), 0 ); + } + } + + if( !slide && currentSlide ) { + var hasFragments = currentSlide.querySelectorAll( '.fragment' ).length > 0; + if( hasFragments ) { + var currentFragment = currentSlide.querySelector( '.current-fragment' ); + if( currentFragment && currentFragment.hasAttribute( 'data-fragment-index' ) ) { + f = parseInt( currentFragment.getAttribute( 'data-fragment-index' ), 10 ); + } + else { + f = currentSlide.querySelectorAll( '.fragment.visible' ).length - 1; + } + } + } + + return { h: h, v: v, f: f }; + + } + + /** + * Retrieves all slides in this presentation. + */ + function getSlides() { + + return toArray( dom.wrapper.querySelectorAll( SLIDES_SELECTOR + ':not(.stack)' )); + + } + + /** + * Returns an array of objects where each object represents the + * attributes on its respective slide. + */ + function getSlidesAttributes() { + + return getSlides().map( function( slide ) { + + var attributes = {}; + for( var i = 0; i < slide.attributes.length; i++ ) { + var attribute = slide.attributes[ i ]; + attributes[ attribute.name ] = attribute.value; + } + return attributes; + + } ); + + } + + /** + * Retrieves the total number of slides in this presentation. + * + * @return {number} + */ + function getTotalSlides() { + + return getSlides().length; + + } + + /** + * Returns the slide element matching the specified index. + * + * @return {HTMLElement} + */ + function getSlide( x, y ) { + + var horizontalSlide = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR )[ x ]; + var verticalSlides = horizontalSlide && horizontalSlide.querySelectorAll( 'section' ); + + if( verticalSlides && verticalSlides.length && typeof y === 'number' ) { + return verticalSlides ? verticalSlides[ y ] : undefined; + } + + return horizontalSlide; + + } + + /** + * Returns the background element for the given slide. + * All slides, even the ones with no background properties + * defined, have a background element so as long as the + * index is valid an element will be returned. + * + * @param {mixed} x Horizontal background index OR a slide + * HTML element + * @param {number} y Vertical background index + * @return {(HTMLElement[]|*)} + */ + function getSlideBackground( x, y ) { + + var slide = typeof x === 'number' ? getSlide( x, y ) : x; + if( slide ) { + return slide.slideBackgroundElement; + } + + return undefined; + + } + + /** + * Retrieves the speaker notes from a slide. Notes can be + * defined in two ways: + * 1. As a data-notes attribute on the slide
    + * 2. As an