├── .gitignore ├── LICENSE ├── _quarto.yml ├── articles ├── html │ ├── README.md │ ├── html.html │ ├── html.qmd │ ├── manifest.json │ └── requirements.txt ├── msword │ ├── msword.docx │ └── msword.qmd └── pdf │ ├── pandoc-user-guide.pdf │ └── pandoc-user-guide.qmd ├── docs ├── articles │ ├── html │ │ └── html.html │ ├── msword │ │ └── msword.docx │ └── pdf │ │ └── pandoc-user-guide.pdf ├── page-layout │ ├── tufte.html │ └── tufte.pdf ├── presentations │ ├── beamer │ │ └── beamer.pdf │ ├── powerpoint │ │ └── powerpoint.pptx │ └── revealjs │ │ └── reveal.html ├── search.json └── site_libs │ ├── bootstrap │ ├── bootstrap-icons.css │ ├── bootstrap-icons.woff │ ├── bootstrap.min.css │ └── bootstrap.min.js │ ├── clipboard │ └── clipboard.min.js │ ├── dygraphs-1.1.1 │ ├── dygraph-combined-dev.js │ ├── dygraph-combined.js │ ├── dygraph.css │ └── shapes.js │ ├── dygraphs-binding-1.1.1.6 │ └── dygraphs.js │ ├── htmlwidgets-1.5.2 │ └── htmlwidgets.js │ ├── jquery-1.11.1 │ ├── AUTHORS.txt │ └── jquery.min.js │ ├── moment-2.8.4 │ ├── moment-timezone-with-data.js │ └── moment.js │ ├── moment-fquarter-1.0.0 │ └── moment-fquarter.min.js │ ├── moment-timezone-0.2.5 │ ├── moment-timezone-with-data.js │ └── moment.js │ ├── quarto-html │ ├── anchor.min.js │ ├── popper.min.js │ ├── quarto-html.min.css │ ├── quarto-syntax-highlighting.css │ ├── quarto.js │ ├── tabby.min.js │ ├── tippy.css │ └── tippy.umd.min.js │ ├── quarto-nav │ └── quarto-nav.js │ ├── quarto-search │ ├── autocomplete.umd.js │ ├── fuse.min.js │ └── quarto-search.js │ └── revealjs │ ├── dist │ ├── reset.css │ ├── reveal.css │ ├── reveal.esm.js │ ├── reveal.esm.js.map │ ├── reveal.js │ ├── reveal.js.map │ └── theme │ │ ├── fonts │ │ ├── league-gothic │ │ │ ├── LICENSE │ │ │ ├── league-gothic.css │ │ │ ├── league-gothic.eot │ │ │ ├── league-gothic.ttf │ │ │ └── league-gothic.woff │ │ └── source-sans-pro │ │ │ ├── LICENSE │ │ │ ├── source-sans-pro-italic.eot │ │ │ ├── source-sans-pro-italic.ttf │ │ │ ├── source-sans-pro-italic.woff │ │ │ ├── source-sans-pro-regular.eot │ │ │ ├── source-sans-pro-regular.ttf │ │ │ ├── source-sans-pro-regular.woff │ │ │ ├── source-sans-pro-semibold.eot │ │ │ ├── source-sans-pro-semibold.ttf │ │ │ ├── source-sans-pro-semibold.woff │ │ │ ├── source-sans-pro-semibolditalic.eot │ │ │ ├── source-sans-pro-semibolditalic.ttf │ │ │ ├── source-sans-pro-semibolditalic.woff │ │ │ └── source-sans-pro.css │ │ └── quarto.css │ └── plugin │ ├── highlight │ ├── highlight.esm.js │ ├── highlight.js │ ├── monokai.css │ ├── plugin.js │ └── zenburn.css │ ├── markdown │ ├── markdown.esm.js │ ├── markdown.js │ └── plugin.js │ ├── math │ ├── katex.js │ ├── math.esm.js │ ├── math.js │ ├── mathjax2.js │ ├── mathjax3.js │ └── plugin.js │ ├── notes │ ├── notes.esm.js │ ├── notes.js │ ├── plugin.js │ └── speaker-view.html │ ├── pdf-export │ ├── pdfexport.js │ └── plugin.yml │ ├── quarto-line-highlight │ ├── line-highlight.css │ ├── line-highlight.js │ └── plugin.yml │ ├── quarto-support │ ├── footer.css │ ├── plugin.yml │ └── support.js │ ├── reveal-menu │ ├── menu.css │ ├── menu.js │ ├── plugin.yml │ ├── quarto-menu.css │ └── quarto-menu.js │ ├── search │ ├── plugin.js │ ├── search.esm.js │ └── search.js │ └── zoom │ ├── plugin.js │ ├── zoom.esm.js │ └── zoom.js ├── page-layout ├── README.md ├── manifest.json ├── requirements.txt ├── skeleton.bib ├── tufte.html ├── tufte.pdf └── tufte.qmd ├── presentations ├── beamer │ ├── beamer.pdf │ ├── beamer.qmd │ └── clemson.png ├── powerpoint │ ├── powerpoint.pptx │ ├── powerpoint.qmd │ ├── ref-arch.png │ ├── servers.png │ └── template.pptx └── revealjs │ ├── README.md │ ├── image │ ├── background_1.png │ ├── background_2.png │ ├── division_1.png │ ├── division_2.png │ ├── documentation.png │ ├── efficiency.png │ ├── format_1_1.png │ ├── format_1_2.png │ ├── format_1_3.png │ ├── format_1_4.png │ ├── format_2_1.png │ ├── format_2_2.png │ ├── format_2_3.png │ ├── format_2_4.png │ ├── gif_0.png │ ├── gif_1.png │ ├── gif_2.png │ ├── gif_3.png │ ├── gif_4.png │ ├── gif_5.png │ ├── gif_6.png │ ├── gif_7.png │ ├── gif_8.png │ ├── gif_9.png │ ├── icjia.png │ ├── il_seal.gif │ ├── interface.gif │ ├── modularity_1.png │ ├── modularity_2.png │ ├── process_new.png │ └── process_old.png │ ├── manifest.json │ ├── requirements.txt │ ├── reveal.html │ ├── reveal.qmd │ └── rsconnect │ └── documents │ └── reveal.qmd │ └── rpubs.com │ └── rpubs │ └── Document.dcf └── quarto-gallery.Rproj /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | 6 | 7 | /.quarto/ 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 quarto-dev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /_quarto.yml: -------------------------------------------------------------------------------- 1 | project: 2 | type: website 3 | output-dir: docs 4 | resources: 5 | - page-layout/tufte.pdf 6 | -------------------------------------------------------------------------------- /articles/html/README.md: -------------------------------------------------------------------------------- 1 | ## HTML article 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /articles/html/html.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /articles/html/html.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Quarto HTML Basics" 3 | author: "Norah Jones" 4 | date: "March 22nd, 2021" 5 | toc: true 6 | format: 7 | html: 8 | html-math-method: katex 9 | code-tools: true 10 | self-contained: true 11 | execute: 12 | warning: false 13 | --- 14 | 15 | ## Introduction 16 | 17 | This a Quarto document. To learn more about Quarto see . 18 | 19 | Click the **Code** button in the header to see the full source code of this document. 20 | 21 | Here we call the R `summary()` function---the function's output is included immediately below: 22 | 23 | ```{r} 24 | summary(cars) 25 | ``` 26 | 27 | ## Plot Output 28 | 29 | You can also embed plots, for example: 30 | 31 | ```{r} 32 | #| label: fig-pressure 33 | #| fig-cap: "Pressure" 34 | #| code-fold: true 35 | 36 | library(ggplot2) 37 | dat <- data.frame(cond = rep(c("A", "B"), each=10), 38 | xvar = 1:20 + rnorm(20,sd=3), 39 | yvar = 1:20 + rnorm(20,sd=3)) 40 | 41 | ggplot(dat, aes(x=xvar, y=yvar)) + 42 | geom_point(shape=1) + 43 | geom_smooth() 44 | ``` 45 | 46 | Note that the `code-fold: true` parameter was added to the code chunk to hide the code by default (click "Code" above the plot to see the code). 47 | 48 | The use of the `label` and `fig-cap` options make this a cross-referenceable figure (see @fig-pressure). 49 | 50 | ## Interactivity 51 | 52 | You can also add interactive plots. For example: 53 | 54 | ```{r} 55 | #| label: fig-temperatures 56 | #| fig-cap: "New Haven Temperatures" 57 | 58 | library(dygraphs) 59 | dygraph(nhtemp) %>% 60 | dyRangeSelector(dateWindow = c("1920-01-01", "1960-01-01")) 61 | ``` 62 | 63 | ## Tables 64 | 65 | Use the `knitr::kable()` function to print tables as HTML: 66 | 67 | ```{r} 68 | knitr::kable(head(ggplot2::diamonds)) 69 | ``` 70 | 71 | 72 | ## LaTeX Math 73 | 74 | You can also include LaTeX math: 75 | 76 | $$ 77 | P\left(A=2\middle|\frac{A^2}{B}>4\right) 78 | $$ 79 | 80 | -------------------------------------------------------------------------------- /articles/html/requirements.txt: -------------------------------------------------------------------------------- 1 | jupyter 2 | -------------------------------------------------------------------------------- /articles/msword/msword.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/articles/msword/msword.docx -------------------------------------------------------------------------------- /articles/msword/msword.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "MS Word" 3 | format: docx 4 | jupyter: python3 5 | --- 6 | 7 | This is a Quarto document. To learn more about Quarto visit . 8 | 9 | ## Plots 10 | 11 | See @fig-polar for an example of rendering plots as figures: 12 | 13 | ```{python} 14 | #| label: fig-polar 15 | #| fig-cap: "A line plot on a polar axis" 16 | 17 | import numpy as np 18 | import matplotlib.pyplot as plt 19 | 20 | r = np.arange(0, 2, 0.01) 21 | theta = 2 * np.pi * r 22 | fig, ax = plt.subplots(subplot_kw={'projection': 'polar'}) 23 | ax.plot(theta, r) 24 | ax.set_rticks([0.5, 1, 1.5, 2]) 25 | ax.grid(True) 26 | plt.show() 27 | ``` 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /articles/pdf/pandoc-user-guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/articles/pdf/pandoc-user-guide.pdf -------------------------------------------------------------------------------- /docs/articles/msword/msword.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/docs/articles/msword/msword.docx -------------------------------------------------------------------------------- /docs/articles/pdf/pandoc-user-guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/docs/articles/pdf/pandoc-user-guide.pdf -------------------------------------------------------------------------------- /docs/page-layout/tufte.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/docs/page-layout/tufte.pdf -------------------------------------------------------------------------------- /docs/presentations/beamer/beamer.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/docs/presentations/beamer/beamer.pdf -------------------------------------------------------------------------------- /docs/presentations/powerpoint/powerpoint.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/docs/presentations/powerpoint/powerpoint.pptx -------------------------------------------------------------------------------- /docs/search.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "objectID": "page-layout/tufte.html#margin-figures", 4 | "href": "page-layout/tufte.html#margin-figures", 5 | "title": "A Quarto Page Layout Example", 6 | "section": "Margin Figures", 7 | "text": "Margin Figures\nImages and graphics play an integral role in Tufte’s work. To place figures in the margin you can use the Quarto chunk option column: margin. For example:\n\nlibrary(ggplot2)\n\nWarning: replacing previous import 'lifecycle::last_warnings' by\n'rlang::last_warnings' when loading 'tibble'\n\nmtcars2 <- mtcars\nmtcars2$am <- factor(\n mtcars$am, labels = c('automatic', 'manual')\n)\nggplot(mtcars2, aes(hp, mpg, color = am)) +\n geom_point() + geom_smooth() +\n theme(legend.position = 'bottom')\n\n\n\n\n\nFigure 1: MPG vs horsepower, colored by transmission.\n\n\n\nNote the use of the fig-cap chunk option to provide a figure caption. You can adjust the proportions of figures using the fig-width and fig-height chunk options. These are specified in inches, and will be automatically scaled down to fit within the handout margin." 8 | }, 9 | { 10 | "objectID": "page-layout/tufte.html#arbitrary-margin-content", 11 | "href": "page-layout/tufte.html#arbitrary-margin-content", 12 | "title": "A Quarto Page Layout Example", 13 | "section": "Arbitrary Margin Content", 14 | "text": "Arbitrary Margin Content\nYou can include anything in the margin by places the class .column-margin on the element. See an example on the right about the first fundamental theorem of calculus.\n\n\nWe know from the first fundamental theorem of calculus that for \\(x\\) in \\([a, b]\\):\n\\[\\frac{d}{dx}\\left( \\int_{a}^{x} f(u)\\,du\\right)=f(x).\\]" 15 | }, 16 | { 17 | "objectID": "page-layout/tufte.html#full-width-figures", 18 | "href": "page-layout/tufte.html#full-width-figures", 19 | "title": "A Quarto Page Layout Example", 20 | "section": "Full Width Figures", 21 | "text": "Full Width Figures\nYou can arrange for figures to span across the entire page by using the chunk option fig-column: page-right.\n\nggplot(diamonds, aes(carat, price)) + geom_smooth() +\n facet_grid(~ cut)\n\n\n\n\nFigure 2: A full width figure.\n\n\n\n\nOther chunk options related to figures can still be used, such as fig-width, fig-cap, and so on. For full width figures, usually fig-width is large and fig-height is small. In the above example, the plot size is \\(11 \\times 3\\)." 22 | }, 23 | { 24 | "objectID": "page-layout/tufte.html#arbitrary-full-width-content", 25 | "href": "page-layout/tufte.html#arbitrary-full-width-content", 26 | "title": "A Quarto Page Layout Example", 27 | "section": "Arbitrary Full Width Content", 28 | "text": "Arbitrary Full Width Content\nAny content can span to the full width of the page, simply place the element in a div and add the class column-page-right. For example, the following code will display its contents as full width.\n::: {.fullwidth}\nAny _full width_ content here.\n:::\nBelow is an example:\n\nR is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under the terms of the GNU General Public License versions 2 or 3. For more information about these matters see https://www.gnu.org/licenses/." 29 | }, 30 | { 31 | "objectID": "page-layout/tufte.html#main-column-figures", 32 | "href": "page-layout/tufte.html#main-column-figures", 33 | "title": "A Quarto Page Layout Example", 34 | "section": "Main Column Figures", 35 | "text": "Main Column Figures\nBesides margin and full width figures, you can of course also include figures constrained to the main column. This is the default type of figures in the LaTeX/HTML output.\n\nggplot(diamonds, aes(cut, price)) + geom_boxplot()\n\n\n\n\nFigure 3: A figure in the main column." 36 | }, 37 | { 38 | "objectID": "page-layout/tufte.html#margin-captions", 39 | "href": "page-layout/tufte.html#margin-captions", 40 | "title": "A Quarto Page Layout Example", 41 | "section": "Margin Captions", 42 | "text": "Margin Captions\nWhen you include a figure constrained to the main column, you can choose to place the figure’s caption in the margin by using the caption-location chunk option. For example:\n\nggplot(diamonds, aes(cut, price)) + geom_boxplot()\n\n\n\n\nFigure 4: A figure with a longer caption. The figure appears in the main column, but the caption is placed in the margin. Caption can even contain elements like a citation such as Xie, Allaire, and Grolemund (2018).\nXie, Yihui, J. J. Allaire, and Garrett Grolemund. 2018. “Tufte Handouts.” In, 137–46. Chapman; Hall/CRC. https://doi.org/10.1201/9781138359444-6." 43 | }, 44 | { 45 | "objectID": "articles/html/html.html#introduction", 46 | "href": "articles/html/html.html#introduction", 47 | "title": "Quarto HTML Basics", 48 | "section": "Introduction", 49 | "text": "Introduction\nThis a Quarto document. To learn more about Quarto see https://quarto.org.\nClick the Code button in the header to see the full source code of this document.\nHere we call the R summary() function—the function’s output is included immediately below:\n\nsummary(cars)\n\n speed dist \n Min. : 4.0 Min. : 2.00 \n 1st Qu.:12.0 1st Qu.: 26.00 \n Median :15.0 Median : 36.00 \n Mean :15.4 Mean : 42.98 \n 3rd Qu.:19.0 3rd Qu.: 56.00 \n Max. :25.0 Max. :120.00" 50 | }, 51 | { 52 | "objectID": "articles/html/html.html#plot-output", 53 | "href": "articles/html/html.html#plot-output", 54 | "title": "Quarto HTML Basics", 55 | "section": "Plot Output", 56 | "text": "Plot Output\nYou can also embed plots, for example:\n\n\nCode\nlibrary(ggplot2)\ndat <- data.frame(cond = rep(c(\"A\", \"B\"), each=10),\n xvar = 1:20 + rnorm(20,sd=3),\n yvar = 1:20 + rnorm(20,sd=3))\n\nggplot(dat, aes(x=xvar, y=yvar)) +\n geom_point(shape=1) + \n geom_smooth() \n\n\n\n\n\nFigure 1: Pressure\n\n\n\n\nNote that the code-fold: true parameter was added to the code chunk to hide the code by default (click “Code” above the plot to see the code).\nThe use of the label and fig-cap options make this a cross-referenceable figure (see fig. 1)." 57 | }, 58 | { 59 | "objectID": "articles/html/html.html#interactivity", 60 | "href": "articles/html/html.html#interactivity", 61 | "title": "Quarto HTML Basics", 62 | "section": "Interactivity", 63 | "text": "Interactivity\nYou can also add interactive plots. For example:\n\nlibrary(dygraphs)\ndygraph(nhtemp) %>% \n dyRangeSelector(dateWindow = c(\"1920-01-01\", \"1960-01-01\"))\n\n\n\n\nFigure 2: New Haven Temperatures" 64 | }, 65 | { 66 | "objectID": "articles/html/html.html#tables", 67 | "href": "articles/html/html.html#tables", 68 | "title": "Quarto HTML Basics", 69 | "section": "Tables", 70 | "text": "Tables\nUse the knitr::kable() function to print tables as HTML:\n\nknitr::kable(head(ggplot2::diamonds))\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\ncarat\ncut\ncolor\nclarity\ndepth\ntable\nprice\nx\ny\nz\n\n\n\n\n0.23\nIdeal\nE\nSI2\n61.5\n55\n326\n3.95\n3.98\n2.43\n\n\n0.21\nPremium\nE\nSI1\n59.8\n61\n326\n3.89\n3.84\n2.31\n\n\n0.23\nGood\nE\nVS1\n56.9\n65\n327\n4.05\n4.07\n2.31\n\n\n0.29\nPremium\nI\nVS2\n62.4\n58\n334\n4.20\n4.23\n2.63\n\n\n0.31\nGood\nJ\nSI2\n63.3\n58\n335\n4.34\n4.35\n2.75\n\n\n0.24\nVery Good\nJ\nVVS2\n62.8\n57\n336\n3.94\n3.96\n2.48" 71 | }, 72 | { 73 | "objectID": "articles/html/html.html#latex-math", 74 | "href": "articles/html/html.html#latex-math", 75 | "title": "Quarto HTML Basics", 76 | "section": "LaTeX Math", 77 | "text": "LaTeX Math\nYou can also include LaTeX math:\n\nP\\left(A=2\\middle|\\frac{A^2}{B}>4\\right)\n\n\n\n\nSource Code\n---\ntitle: \"Quarto HTML Basics\"\nauthor: \"Norah Jones\"\ndate: \"March 22nd, 2021\"\ntoc: true\nformat:\n html:\n html-math-method: katex\n code-tools: true\n self-contained: true\nexecute:\n warning: false\n---\n\n## Introduction\n\nThis a Quarto document. To learn more about Quarto see .\n\nClick the **Code** button in the header to see the full source code of this document.\n\nHere we call the R `summary()` function---the function's output is included immediately below:\n\n```{r}\nsummary(cars)\n```\n\n## Plot Output\n\nYou can also embed plots, for example:\n\n```{r}\n#| label: fig-pressure\n#| fig-cap: \"Pressure\"\n#| code-fold: true\n\nlibrary(ggplot2)\ndat <- data.frame(cond = rep(c(\"A\", \"B\"), each=10),\n xvar = 1:20 + rnorm(20,sd=3),\n yvar = 1:20 + rnorm(20,sd=3))\n\nggplot(dat, aes(x=xvar, y=yvar)) +\n geom_point(shape=1) + \n geom_smooth() \n```\n\nNote that the `code-fold: true` parameter was added to the code chunk to hide the code by default (click \"Code\" above the plot to see the code).\n\nThe use of the `label` and `fig-cap` options make this a cross-referenceable figure (see @fig-pressure).\n\n## Interactivity\n\nYou can also add interactive plots. For example:\n\n```{r}\n#| label: fig-temperatures\n#| fig-cap: \"New Haven Temperatures\"\n\nlibrary(dygraphs)\ndygraph(nhtemp) %>% \n dyRangeSelector(dateWindow = c(\"1920-01-01\", \"1960-01-01\"))\n```\n\n## Tables\n\nUse the `knitr::kable()` function to print tables as HTML:\n\n```{r}\nknitr::kable(head(ggplot2::diamonds))\n```\n\n\n## LaTeX Math\n\nYou can also include LaTeX math:\n\n$$\nP\\left(A=2\\middle|\\frac{A^2}{B}>4\\right)\n$$" 78 | }, 79 | { 80 | "objectID": "presentations/revealjs/reveal.html#agenda", 81 | "href": "presentations/revealjs/reveal.html#agenda", 82 | "title": "Modernizing R&A Data Products With Python", 83 | "section": "Agenda", 84 | "text": "Agenda\n\nBackground\nDesign and Implementation\nShowcase\nPath forward" 85 | }, 86 | { 87 | "objectID": "presentations/revealjs/reveal.html#motivation", 88 | "href": "presentations/revealjs/reveal.html#motivation", 89 | "title": "Modernizing R&A Data Products With Python", 90 | "section": "Motivation", 91 | "text": "Motivation\n\nTime-consuming\nDifficult to maintain\nSuboptimal tools\nOutmoded data format\nOverreliance on a single individual" 92 | }, 93 | { 94 | "objectID": "presentations/revealjs/reveal.html#what-we-did", 95 | "href": "presentations/revealjs/reveal.html#what-we-did", 96 | "title": "Modernizing R&A Data Products With Python", 97 | "section": "What we did", 98 | "text": "What we did\n\nAutomation\nModular and flexible design\nFast and efficient tools\nMachine-friendly format\nPotential division of labor" 99 | }, 100 | { 101 | "objectID": "presentations/revealjs/reveal.html#automation", 102 | "href": "presentations/revealjs/reveal.html#automation", 103 | "title": "Modernizing R&A Data Products With Python", 104 | "section": "Automation", 105 | "text": "Automation" 106 | }, 107 | { 108 | "objectID": "presentations/revealjs/reveal.html#modularity", 109 | "href": "presentations/revealjs/reveal.html#modularity", 110 | "title": "Modernizing R&A Data Products With Python", 111 | "section": "Modularity", 112 | "text": "Modularity" 113 | }, 114 | { 115 | "objectID": "presentations/revealjs/reveal.html#modularity-1", 116 | "href": "presentations/revealjs/reveal.html#modularity-1", 117 | "title": "Modernizing R&A Data Products With Python", 118 | "section": "Modularity", 119 | "text": "Modularity" 120 | }, 121 | { 122 | "objectID": "presentations/revealjs/reveal.html#efficiency", 123 | "href": "presentations/revealjs/reveal.html#efficiency", 124 | "title": "Modernizing R&A Data Products With Python", 125 | "section": "Efficiency", 126 | "text": "Efficiency" 127 | }, 128 | { 129 | "objectID": "presentations/revealjs/reveal.html#format-old", 130 | "href": "presentations/revealjs/reveal.html#format-old", 131 | "title": "Modernizing R&A Data Products With Python", 132 | "section": "Format (old)", 133 | "text": "Format (old)" 134 | }, 135 | { 136 | "objectID": "presentations/revealjs/reveal.html#format-old-1", 137 | "href": "presentations/revealjs/reveal.html#format-old-1", 138 | "title": "Modernizing R&A Data Products With Python", 139 | "section": "Format (old)", 140 | "text": "Format (old)" 141 | }, 142 | { 143 | "objectID": "presentations/revealjs/reveal.html#format-old-2", 144 | "href": "presentations/revealjs/reveal.html#format-old-2", 145 | "title": "Modernizing R&A Data Products With Python", 146 | "section": "Format (old)", 147 | "text": "Format (old)" 148 | }, 149 | { 150 | "objectID": "presentations/revealjs/reveal.html#format-old-3", 151 | "href": "presentations/revealjs/reveal.html#format-old-3", 152 | "title": "Modernizing R&A Data Products With Python", 153 | "section": "Format (old)", 154 | "text": "Format (old)" 155 | }, 156 | { 157 | "objectID": "presentations/revealjs/reveal.html#format-new", 158 | "href": "presentations/revealjs/reveal.html#format-new", 159 | "title": "Modernizing R&A Data Products With Python", 160 | "section": "Format (new)", 161 | "text": "Format (new)" 162 | }, 163 | { 164 | "objectID": "presentations/revealjs/reveal.html#format-new-1", 165 | "href": "presentations/revealjs/reveal.html#format-new-1", 166 | "title": "Modernizing R&A Data Products With Python", 167 | "section": "Format (new)", 168 | "text": "Format (new)" 169 | }, 170 | { 171 | "objectID": "presentations/revealjs/reveal.html#format-new-2", 172 | "href": "presentations/revealjs/reveal.html#format-new-2", 173 | "title": "Modernizing R&A Data Products With Python", 174 | "section": "Format (new)", 175 | "text": "Format (new)" 176 | }, 177 | { 178 | "objectID": "presentations/revealjs/reveal.html#format-new-3", 179 | "href": "presentations/revealjs/reveal.html#format-new-3", 180 | "title": "Modernizing R&A Data Products With Python", 181 | "section": "Format (new)", 182 | "text": "Format (new)" 183 | }, 184 | { 185 | "objectID": "presentations/revealjs/reveal.html#division-of-labor", 186 | "href": "presentations/revealjs/reveal.html#division-of-labor", 187 | "title": "Modernizing R&A Data Products With Python", 188 | "section": "Division of labor", 189 | "text": "Division of labor" 190 | }, 191 | { 192 | "objectID": "presentations/revealjs/reveal.html#division-of-labor-1", 193 | "href": "presentations/revealjs/reveal.html#division-of-labor-1", 194 | "title": "Modernizing R&A Data Products With Python", 195 | "section": "Division of labor", 196 | "text": "Division of labor" 197 | } 198 | ] -------------------------------------------------------------------------------- /docs/site_libs/bootstrap/bootstrap-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/docs/site_libs/bootstrap/bootstrap-icons.woff -------------------------------------------------------------------------------- /docs/site_libs/clipboard/clipboard.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * clipboard.js v2.0.6 3 | * https://clipboardjs.com/ 4 | * 5 | * Licensed MIT © Zeno Rocha 6 | */ 7 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={134:(t,e,n)=>{"use strict";n.d(e,{default:()=>r});var e=n(817),o=n.n(e);function i(t){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function a(t,e){for(var n=0;n{var e;"undefined"==typeof Element||Element.prototype.matches||((e=Element.prototype).matches=e.matchesSelector||e.mozMatchesSelector||e.msMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector),t.exports=function(t,e){for(;t&&9!==t.nodeType;){if("function"==typeof t.matches&&t.matches(e))return t;t=t.parentNode}}},438:(t,e,n)=>{var a=n(828);function i(t,e,n,r,o){var i=function(e,n,t,r){return function(t){t.delegateTarget=a(t.target,n),t.delegateTarget&&r.call(e,t)}}.apply(this,arguments);return t.addEventListener(n,i,o),{destroy:function(){t.removeEventListener(n,i,o)}}}t.exports=function(t,e,n,r,o){return"function"==typeof t.addEventListener?i.apply(null,arguments):"function"==typeof n?i.bind(null,document).apply(null,arguments):("string"==typeof t&&(t=document.querySelectorAll(t)),Array.prototype.map.call(t,function(t){return i(t,e,n,r,o)}))}},879:(t,n)=>{n.node=function(t){return void 0!==t&&t instanceof HTMLElement&&1===t.nodeType},n.nodeList=function(t){var e=Object.prototype.toString.call(t);return void 0!==t&&("[object NodeList]"===e||"[object HTMLCollection]"===e)&&"length"in t&&(0===t.length||n.node(t[0]))},n.string=function(t){return"string"==typeof t||t instanceof String},n.fn=function(t){return"[object Function]"===Object.prototype.toString.call(t)}},370:(t,e,n)=>{var u=n(879),s=n(438);t.exports=function(t,e,n){if(!t&&!e&&!n)throw new Error("Missing required arguments");if(!u.string(e))throw new TypeError("Second argument must be a String");if(!u.fn(n))throw new TypeError("Third argument must be a Function");if(u.node(t))return c=e,l=n,(a=t).addEventListener(c,l),{destroy:function(){a.removeEventListener(c,l)}};if(u.nodeList(t))return r=t,o=e,i=n,Array.prototype.forEach.call(r,function(t){t.addEventListener(o,i)}),{destroy:function(){Array.prototype.forEach.call(r,function(t){t.removeEventListener(o,i)})}};if(u.string(t))return t=t,e=e,n=n,s(document.body,t,e,n);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList");var r,o,i,a,c,l}},817:t=>{t.exports=function(t){var e,n="SELECT"===t.nodeName?(t.focus(),t.value):"INPUT"===t.nodeName||"TEXTAREA"===t.nodeName?((e=t.hasAttribute("readonly"))||t.setAttribute("readonly",""),t.select(),t.setSelectionRange(0,t.value.length),e||t.removeAttribute("readonly"),t.value):(t.hasAttribute("contenteditable")&&t.focus(),n=window.getSelection(),(e=document.createRange()).selectNodeContents(t),n.removeAllRanges(),n.addRange(e),n.toString());return n}},279:t=>{function e(){}e.prototype={on:function(t,e,n){var r=this.e||(this.e={});return(r[t]||(r[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){var r=this;function o(){r.off(t,o),e.apply(n,arguments)}return o._=e,this.on(t,o,n)},emit:function(t){for(var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),r=0,o=n.length;r{var e=t&&t.__esModule?()=>t.default:()=>t;return r.d(e,{a:e}),e},r.d=(t,e)=>{for(var n in e)r.o(e,n)&&!r.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},r.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r(134).default;function r(t){if(o[t])return o[t].exports;var e=o[t]={exports:{}};return n[t](e,e.exports,r),e.exports}var n,o}); -------------------------------------------------------------------------------- /docs/site_libs/dygraphs-1.1.1/dygraph.css: -------------------------------------------------------------------------------- 1 | 2 | div .dygraphs input[type="text"] { 3 | width: 25px; 4 | } 5 | 6 | div .qt .dygraph-axis-label { 7 | font-size: 11px; 8 | } -------------------------------------------------------------------------------- /docs/site_libs/dygraphs-1.1.1/shapes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2011 Dan Vanderkam (danvdk@gmail.com) 4 | * MIT-licensed (http://opensource.org/licenses/MIT) 5 | */ 6 | 7 | /** 8 | * @fileoverview 9 | * Including this file will add several additional shapes to Dygraph.Circles 10 | * which can be passed to drawPointCallback. 11 | * See tests/custom-circles.html for usage. 12 | */ 13 | 14 | (function() { 15 | 16 | /** 17 | * @param {!CanvasRenderingContext2D} ctx the canvas context 18 | * @param {number} sides the number of sides in the shape. 19 | * @param {number} radius the radius of the image. 20 | * @param {number} cx center x coordate 21 | * @param {number} cy center y coordinate 22 | * @param {number=} rotationRadians the shift of the initial angle, in radians. 23 | * @param {number=} delta the angle shift for each line. If missing, creates a 24 | * regular polygon. 25 | */ 26 | var regularShape = function( 27 | ctx, sides, radius, cx, cy, rotationRadians, delta) { 28 | rotationRadians = rotationRadians || 0; 29 | delta = delta || Math.PI * 2 / sides; 30 | 31 | ctx.beginPath(); 32 | var initialAngle = rotationRadians; 33 | var angle = initialAngle; 34 | 35 | var computeCoordinates = function() { 36 | var x = cx + (Math.sin(angle) * radius); 37 | var y = cy + (-Math.cos(angle) * radius); 38 | return [x, y]; 39 | }; 40 | 41 | var initialCoordinates = computeCoordinates(); 42 | var x = initialCoordinates[0]; 43 | var y = initialCoordinates[1]; 44 | ctx.moveTo(x, y); 45 | 46 | for (var idx = 0; idx < sides; idx++) { 47 | angle = (idx == sides - 1) ? initialAngle : (angle + delta); 48 | var coords = computeCoordinates(); 49 | ctx.lineTo(coords[0], coords[1]); 50 | } 51 | ctx.fill(); 52 | ctx.stroke(); 53 | }; 54 | 55 | /** 56 | * TODO(danvk): be more specific on the return type. 57 | * @param {number} sides 58 | * @param {number=} rotationRadians 59 | * @param {number=} delta 60 | * @return {Function} 61 | * @private 62 | */ 63 | var shapeFunction = function(sides, rotationRadians, delta) { 64 | return function(g, name, ctx, cx, cy, color, radius) { 65 | ctx.strokeStyle = color; 66 | ctx.fillStyle = "white"; 67 | regularShape(ctx, sides, radius, cx, cy, rotationRadians, delta); 68 | }; 69 | }; 70 | 71 | var customCircles = { 72 | TRIANGLE : shapeFunction(3), 73 | SQUARE : shapeFunction(4, Math.PI / 4), 74 | DIAMOND : shapeFunction(4), 75 | PENTAGON : shapeFunction(5), 76 | HEXAGON : shapeFunction(6), 77 | CIRCLE : function(g, name, ctx, cx, cy, color, radius) { 78 | ctx.beginPath(); 79 | ctx.strokeStyle = color; 80 | ctx.fillStyle = "white"; 81 | ctx.arc(cx, cy, radius, 0, 2 * Math.PI, false); 82 | ctx.fill(); 83 | ctx.stroke(); 84 | }, 85 | STAR : shapeFunction(5, 0, 4 * Math.PI / 5), 86 | PLUS : function(g, name, ctx, cx, cy, color, radius) { 87 | ctx.strokeStyle = color; 88 | 89 | ctx.beginPath(); 90 | ctx.moveTo(cx + radius, cy); 91 | ctx.lineTo(cx - radius, cy); 92 | ctx.closePath(); 93 | ctx.stroke(); 94 | 95 | ctx.beginPath(); 96 | ctx.moveTo(cx, cy + radius); 97 | ctx.lineTo(cx, cy - radius); 98 | ctx.closePath(); 99 | ctx.stroke(); 100 | }, 101 | EX : function(g, name, ctx, cx, cy, color, radius) { 102 | ctx.strokeStyle = color; 103 | 104 | ctx.beginPath(); 105 | ctx.moveTo(cx + radius, cy + radius); 106 | ctx.lineTo(cx - radius, cy - radius); 107 | ctx.closePath(); 108 | ctx.stroke(); 109 | 110 | ctx.beginPath(); 111 | ctx.moveTo(cx + radius, cy - radius); 112 | ctx.lineTo(cx - radius, cy + radius); 113 | ctx.closePath(); 114 | ctx.stroke(); 115 | } 116 | }; 117 | 118 | for (var k in customCircles) { 119 | if (!customCircles.hasOwnProperty(k)) continue; 120 | Dygraph.Circles[k] = customCircles[k]; 121 | } 122 | 123 | })(); 124 | -------------------------------------------------------------------------------- /docs/site_libs/jquery-1.11.1/AUTHORS.txt: -------------------------------------------------------------------------------- 1 | Authors ordered by first contribution. 2 | 3 | John Resig 4 | Gilles van den Hoven 5 | Michael Geary 6 | Stefan Petre 7 | Yehuda Katz 8 | Corey Jewett 9 | Klaus Hartl 10 | Franck Marcia 11 | Jörn Zaefferer 12 | Paul Bakaus 13 | Brandon Aaron 14 | Mike Alsup 15 | Dave Methvin 16 | Ed Engelhardt 17 | Sean Catchpole 18 | Paul Mclanahan 19 | David Serduke 20 | Richard D. Worth 21 | Scott González 22 | Ariel Flesler 23 | Jon Evans 24 | TJ Holowaychuk 25 | Michael Bensoussan 26 | Robert Katić 27 | Louis-Rémi Babé 28 | Earle Castledine 29 | Damian Janowski 30 | Rich Dougherty 31 | Kim Dalsgaard 32 | Andrea Giammarchi 33 | Mark Gibson 34 | Karl Swedberg 35 | Justin Meyer 36 | Ben Alman 37 | James Padolsey 38 | David Petersen 39 | Batiste Bieler 40 | Alexander Farkas 41 | Rick Waldron 42 | Filipe Fortes 43 | Neeraj Singh 44 | Paul Irish 45 | Iraê Carvalho 46 | Matt Curry 47 | Michael Monteleone 48 | Noah Sloan 49 | Tom Viner 50 | Douglas Neiner 51 | Adam J. Sontag 52 | Dave Reed 53 | Ralph Whitbeck 54 | Carl Fürstenberg 55 | Jacob Wright 56 | J. Ryan Stinnett 57 | unknown 58 | temp01 59 | Heungsub Lee 60 | Colin Snover 61 | Ryan W Tenney 62 | Pinhook 63 | Ron Otten 64 | Jephte Clain 65 | Anton Matzneller 66 | Alex Sexton 67 | Dan Heberden 68 | Henri Wiechers 69 | Russell Holbrook 70 | Julian Aubourg 71 | Gianni Alessandro Chiappetta 72 | Scott Jehl 73 | James Burke 74 | Jonas Pfenniger 75 | Xavi Ramirez 76 | Jared Grippe 77 | Sylvester Keil 78 | Brandon Sterne 79 | Mathias Bynens 80 | Timmy Willison 81 | Corey Frang 82 | Digitalxero 83 | Anton Kovalyov 84 | David Murdoch 85 | Josh Varner 86 | Charles McNulty 87 | Jordan Boesch 88 | Jess Thrysoee 89 | Michael Murray 90 | Lee Carpenter 91 | Alexis Abril 92 | Rob Morgan 93 | John Firebaugh 94 | Sam Bisbee 95 | Gilmore Davidson 96 | Brian Brennan 97 | Xavier Montillet 98 | Daniel Pihlstrom 99 | Sahab Yazdani 100 | avaly 101 | Scott Hughes 102 | Mike Sherov 103 | Greg Hazel 104 | Schalk Neethling 105 | Denis Knauf 106 | Timo Tijhof 107 | Steen Nielsen 108 | Anton Ryzhov 109 | Shi Chuan 110 | Berker Peksag 111 | Toby Brain 112 | Matt Mueller 113 | Justin 114 | Daniel Herman 115 | Oleg Gaidarenko 116 | Richard Gibson 117 | Rafaël Blais Masson 118 | cmc3cn <59194618@qq.com> 119 | Joe Presbrey 120 | Sindre Sorhus 121 | Arne de Bree 122 | Vladislav Zarakovsky 123 | Andrew E Monat 124 | Oskari 125 | Joao Henrique de Andrade Bruni 126 | tsinha 127 | Matt Farmer 128 | Trey Hunner 129 | Jason Moon 130 | Jeffery To 131 | Kris Borchers 132 | Vladimir Zhuravlev 133 | Jacob Thornton 134 | Chad Killingsworth 135 | Nowres Rafid 136 | David Benjamin 137 | Uri Gilad 138 | Chris Faulkner 139 | Elijah Manor 140 | Daniel Chatfield 141 | Nikita Govorov 142 | Wesley Walser 143 | Mike Pennisi 144 | Markus Staab 145 | Dave Riddle 146 | Callum Macrae 147 | Benjamin Truyman 148 | James Huston 149 | Erick Ruiz de Chávez 150 | David Bonner 151 | Akintayo Akinwunmi 152 | MORGAN 153 | Ismail Khair 154 | Carl Danley 155 | Mike Petrovich 156 | Greg Lavallee 157 | Daniel Gálvez 158 | Sai Lung Wong 159 | Tom H Fuertes 160 | Roland Eckl 161 | Jay Merrifield 162 | Allen J Schmidt Jr 163 | Jonathan Sampson 164 | Marcel Greter 165 | Matthias Jäggli 166 | David Fox 167 | Yiming He 168 | Devin Cooper 169 | Paul Ramos 170 | Rod Vagg 171 | Bennett Sorbo 172 | Sebastian Burkhard 173 | nanto 174 | Danil Somsikov 175 | Ryunosuke SATO 176 | Jean Boussier 177 | Adam Coulombe 178 | Andrew Plummer 179 | Mark Raddatz 180 | Dmitry Gusev 181 | Michał Gołębiowski 182 | Nguyen Phuc Lam 183 | Tom H Fuertes 184 | Brandon Johnson 185 | Jason Bedard 186 | Kyle Robinson Young 187 | Renato Oliveira dos Santos 188 | Chris Talkington 189 | Eddie Monge 190 | Terry Jones 191 | Jason Merino 192 | Jeremy Dunck 193 | Chris Price 194 | Amey Sakhadeo 195 | Anthony Ryan 196 | Dominik D. Geyer 197 | George Kats 198 | Lihan Li 199 | Ronny Springer 200 | Marian Sollmann 201 | Corey Frang 202 | Chris Antaki 203 | Noah Hamann 204 | David Hong 205 | Jakob Stoeck 206 | Christopher Jones 207 | Forbes Lindesay 208 | John Paul 209 | S. Andrew Sheppard 210 | Leonardo Balter 211 | Roman Reiß 212 | Benjy Cui 213 | Rodrigo Rosenfeld Rosas 214 | John Hoven 215 | Christian Kosmowski 216 | Liang Peng 217 | TJ VanToll 218 | -------------------------------------------------------------------------------- /docs/site_libs/moment-fquarter-1.0.0/moment-fquarter.min.js: -------------------------------------------------------------------------------- 1 | (function(){function n(n){return n.fn.fquarter=function(n){var u=this.lang()._quarter||"Q",t={},r,i=null;return n=n||4,n>1?(r=this.subtract("months",n-1),i=r.clone().add("years",1)):r=this,t.quarter=Math.ceil((r.month()+1)/3),t.year=r.year(),t.nextYear=i?i.year():i,t.toString=function(){var n=u+t.quarter+" "+t.year;return i?n+"/"+i.format("YY"):n},t},n}typeof define=="function"&&define.amd?define("moment-fquarter",["moment"],n):typeof module!="undefined"?module.exports=n(require("moment")):typeof window!="undefined"&&window.moment&&n(window.moment)}).apply(this); -------------------------------------------------------------------------------- /docs/site_libs/quarto-html/anchor.min.js: -------------------------------------------------------------------------------- 1 | // @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat 2 | // 3 | // AnchorJS - v4.3.0 - 2020-10-21 4 | // https://www.bryanbraun.com/anchorjs/ 5 | // Copyright (c) 2020 Bryan Braun; Licensed MIT 6 | // 7 | // @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat 8 | !function(A,e){"use strict";"function"==typeof define&&define.amd?define([],e):"object"==typeof module&&module.exports?module.exports=e():(A.AnchorJS=e(),A.anchors=new A.AnchorJS)}(this,function(){"use strict";return function(A){function d(A){A.icon=Object.prototype.hasOwnProperty.call(A,"icon")?A.icon:"",A.visible=Object.prototype.hasOwnProperty.call(A,"visible")?A.visible:"hover",A.placement=Object.prototype.hasOwnProperty.call(A,"placement")?A.placement:"right",A.ariaLabel=Object.prototype.hasOwnProperty.call(A,"ariaLabel")?A.ariaLabel:"Anchor",A.class=Object.prototype.hasOwnProperty.call(A,"class")?A.class:"",A.base=Object.prototype.hasOwnProperty.call(A,"base")?A.base:"",A.truncate=Object.prototype.hasOwnProperty.call(A,"truncate")?Math.floor(A.truncate):64,A.titleText=Object.prototype.hasOwnProperty.call(A,"titleText")?A.titleText:""}function f(A){var e;if("string"==typeof A||A instanceof String)e=[].slice.call(document.querySelectorAll(A));else{if(!(Array.isArray(A)||A instanceof NodeList))throw new TypeError("The selector provided to AnchorJS was invalid.");e=[].slice.call(A)}return e}this.options=A||{},this.elements=[],d(this.options),this.isTouchDevice=function(){return Boolean("ontouchstart"in window||window.TouchEvent||window.DocumentTouch&&document instanceof DocumentTouch)},this.add=function(A){var e,t,o,n,i,s,a,r,c,l,h,u,p=[];if(d(this.options),"touch"===(h=this.options.visible)&&(h=this.isTouchDevice()?"always":"hover"),0===(e=f(A=A||"h2, h3, h4, h5, h6")).length)return this;for(!function(){if(null!==document.head.querySelector("style.anchorjs"))return;var A,e=document.createElement("style");e.className="anchorjs",e.appendChild(document.createTextNode("")),void 0===(A=document.head.querySelector('[rel="stylesheet"],style'))?document.head.appendChild(e):document.head.insertBefore(e,A);e.sheet.insertRule(".anchorjs-link{opacity:0;text-decoration:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}",e.sheet.cssRules.length),e.sheet.insertRule(":hover>.anchorjs-link,.anchorjs-link:focus{opacity:1}",e.sheet.cssRules.length),e.sheet.insertRule("[data-anchorjs-icon]::after{content:attr(data-anchorjs-icon)}",e.sheet.cssRules.length),e.sheet.insertRule('@font-face{font-family:anchorjs-icons;src:url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype")}',e.sheet.cssRules.length)}(),t=document.querySelectorAll("[id]"),o=[].map.call(t,function(A){return A.id}),i=0;i\]./()*\\\n\t\b\v\u00A0]/g,"-").replace(/-{2,}/g,"-").substring(0,this.options.truncate).replace(/^-+|-+$/gm,"").toLowerCase()},this.hasAnchorJSLink=function(A){var e=A.firstChild&&-1<(" "+A.firstChild.className+" ").indexOf(" anchorjs-link "),t=A.lastChild&&-1<(" "+A.lastChild.className+" ").indexOf(" anchorjs-link ");return e||t||!1}}}); 9 | // @license-end -------------------------------------------------------------------------------- /docs/site_libs/quarto-html/quarto-html.min.css: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/site_libs/quarto-html/quarto-syntax-highlighting.css: -------------------------------------------------------------------------------- 1 | /* quarto syntax highlight colors */ 2 | :root { 3 | --quarto-hl-ot-color: #007BA5; 4 | --quarto-hl-at-color: inherit; 5 | --quarto-hl-ss-color: #20794D; 6 | --quarto-hl-an-color: #5E5E5E; 7 | --quarto-hl-fu-color: #4758AB; 8 | --quarto-hl-st-color: #20794D; 9 | --quarto-hl-cf-color: #007BA5; 10 | --quarto-hl-op-color: #5E5E5E; 11 | --quarto-hl-er-color: #AD0000; 12 | --quarto-hl-bn-color: #AD0000; 13 | --quarto-hl-al-color: #AD0000; 14 | --quarto-hl-va-color: #111111; 15 | --quarto-hl-bu-color: inherit; 16 | --quarto-hl-ex-color: inherit; 17 | --quarto-hl-pp-color: #AD0000; 18 | --quarto-hl-in-color: #5E5E5E; 19 | --quarto-hl-vs-color: #20794D; 20 | --quarto-hl-wa-color: #5E5E5E; 21 | --quarto-hl-do-color: #5E5E5E; 22 | --quarto-hl-im-color: inherit; 23 | --quarto-hl-ch-color: #20794D; 24 | --quarto-hl-dt-color: #AD0000; 25 | --quarto-hl-fl-color: #AD0000; 26 | --quarto-hl-co-color: #5E5E5E; 27 | --quarto-hl-cv-color: #5E5E5E; 28 | --quarto-hl-cn-color: #8f5902; 29 | --quarto-hl-sc-color: #5E5E5E; 30 | --quarto-hl-dv-color: #AD0000; 31 | --quarto-hl-kw-color: #007BA5; 32 | } 33 | 34 | /* other quarto variables */ 35 | :root { 36 | --quarto-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; 37 | } 38 | 39 | code span { 40 | color: #007BA5; 41 | } 42 | 43 | div.sourceCode { 44 | color: #007BA5; 45 | } 46 | 47 | code span.ot { 48 | color: #007BA5; 49 | } 50 | 51 | code span.ss { 52 | color: #20794D; 53 | } 54 | 55 | code span.an { 56 | color: #5E5E5E; 57 | } 58 | 59 | code span.fu { 60 | color: #4758AB; 61 | } 62 | 63 | code span.st { 64 | color: #20794D; 65 | } 66 | 67 | code span.cf { 68 | color: #007BA5; 69 | } 70 | 71 | code span.op { 72 | color: #5E5E5E; 73 | } 74 | 75 | code span.er { 76 | color: #AD0000; 77 | } 78 | 79 | code span.bn { 80 | color: #AD0000; 81 | } 82 | 83 | code span.al { 84 | color: #AD0000; 85 | } 86 | 87 | code span.va { 88 | color: #111111; 89 | } 90 | 91 | code span.pp { 92 | color: #AD0000; 93 | } 94 | 95 | code span.in { 96 | color: #5E5E5E; 97 | } 98 | 99 | code span.vs { 100 | color: #20794D; 101 | } 102 | 103 | code span.wa { 104 | color: #5E5E5E; 105 | font-style: italic; 106 | } 107 | 108 | code span.do { 109 | color: #5E5E5E; 110 | font-style: italic; 111 | } 112 | 113 | code span.ch { 114 | color: #20794D; 115 | } 116 | 117 | code span.dt { 118 | color: #AD0000; 119 | } 120 | 121 | code span.fl { 122 | color: #AD0000; 123 | } 124 | 125 | code span.co { 126 | color: #5E5E5E; 127 | } 128 | 129 | code span.cv { 130 | color: #5E5E5E; 131 | font-style: italic; 132 | } 133 | 134 | code span.cn { 135 | color: #8f5902; 136 | } 137 | 138 | code span.sc { 139 | color: #5E5E5E; 140 | } 141 | 142 | code span.dv { 143 | color: #AD0000; 144 | } 145 | 146 | code span.kw { 147 | color: #007BA5; 148 | } 149 | -------------------------------------------------------------------------------- /docs/site_libs/quarto-html/tabby.min.js: -------------------------------------------------------------------------------- 1 | (function (root, factory) { 2 | if (typeof define === "function" && define.amd) { 3 | define([], function () { 4 | return factory(root); 5 | }); 6 | } else if (typeof exports === "object") { 7 | module.exports = factory(root); 8 | } else { 9 | root.Tabby = factory(root); 10 | } 11 | })( 12 | typeof global !== "undefined" 13 | ? global 14 | : typeof window !== "undefined" 15 | ? window 16 | : this, 17 | function (window) { 18 | "use strict"; 19 | 20 | // 21 | // Variables 22 | // 23 | 24 | var defaults = { 25 | idPrefix: "tabby-toggle_", 26 | default: "[data-tabby-default]", 27 | }; 28 | 29 | // 30 | // Methods 31 | // 32 | 33 | /** 34 | * Merge two or more objects together. 35 | * @param {Object} objects The objects to merge together 36 | * @returns {Object} Merged values of defaults and options 37 | */ 38 | var extend = function () { 39 | var merged = {}; 40 | Array.prototype.forEach.call(arguments, function (obj) { 41 | for (var key in obj) { 42 | if (!obj.hasOwnProperty(key)) return; 43 | merged[key] = obj[key]; 44 | } 45 | }); 46 | return merged; 47 | }; 48 | 49 | /** 50 | * Emit a custom event 51 | * @param {String} type The event type 52 | * @param {Node} tab The tab to attach the event to 53 | * @param {Node} details Details about the event 54 | */ 55 | var emitEvent = function (tab, details) { 56 | // Create a new event 57 | var event; 58 | if (typeof window.CustomEvent === "function") { 59 | event = new CustomEvent("tabby", { 60 | bubbles: true, 61 | cancelable: true, 62 | detail: details, 63 | }); 64 | } else { 65 | event = document.createEvent("CustomEvent"); 66 | event.initCustomEvent("tabby", true, true, details); 67 | } 68 | 69 | // Dispatch the event 70 | tab.dispatchEvent(event); 71 | }; 72 | 73 | var focusHandler = function (event) { 74 | toggle(event.target); 75 | }; 76 | 77 | var getKeyboardFocusableElements = function (element) { 78 | return [ 79 | ...element.querySelectorAll( 80 | 'a[href], button, input, textarea, select, details,[tabindex]:not([tabindex="-1"])' 81 | ), 82 | ].filter( 83 | (el) => !el.hasAttribute("disabled") && !el.getAttribute("aria-hidden") 84 | ); 85 | }; 86 | 87 | /** 88 | * Remove roles and attributes from a tab and its content 89 | * @param {Node} tab The tab 90 | * @param {Node} content The tab content 91 | * @param {Object} settings User settings and options 92 | */ 93 | var destroyTab = function (tab, content, settings) { 94 | // Remove the generated ID 95 | if (tab.id.slice(0, settings.idPrefix.length) === settings.idPrefix) { 96 | tab.id = ""; 97 | } 98 | 99 | // remove event listener 100 | tab.removeEventListener("focus", focusHandler, true); 101 | 102 | // Remove roles 103 | tab.removeAttribute("role"); 104 | tab.removeAttribute("aria-controls"); 105 | tab.removeAttribute("aria-selected"); 106 | tab.removeAttribute("tabindex"); 107 | tab.closest("li").removeAttribute("role"); 108 | content.removeAttribute("role"); 109 | content.removeAttribute("aria-labelledby"); 110 | content.removeAttribute("hidden"); 111 | }; 112 | 113 | /** 114 | * Add the required roles and attributes to a tab and its content 115 | * @param {Node} tab The tab 116 | * @param {Node} content The tab content 117 | * @param {Object} settings User settings and options 118 | */ 119 | var setupTab = function (tab, content, settings) { 120 | // Give tab an ID if it doesn't already have one 121 | if (!tab.id) { 122 | tab.id = settings.idPrefix + content.id; 123 | } 124 | 125 | // Add roles 126 | tab.setAttribute("role", "tab"); 127 | tab.setAttribute("aria-controls", content.id); 128 | tab.closest("li").setAttribute("role", "presentation"); 129 | content.setAttribute("role", "tabpanel"); 130 | content.setAttribute("aria-labelledby", tab.id); 131 | 132 | // Add selected state 133 | if (tab.matches(settings.default)) { 134 | tab.setAttribute("aria-selected", "true"); 135 | } else { 136 | tab.setAttribute("aria-selected", "false"); 137 | content.setAttribute("hidden", "hidden"); 138 | } 139 | 140 | // add focus event listender 141 | tab.addEventListener("focus", focusHandler); 142 | }; 143 | 144 | /** 145 | * Hide a tab and its content 146 | * @param {Node} newTab The new tab that's replacing it 147 | */ 148 | var hide = function (newTab) { 149 | // Variables 150 | var tabGroup = newTab.closest('[role="tablist"]'); 151 | if (!tabGroup) return {}; 152 | var tab = tabGroup.querySelector('[role="tab"][aria-selected="true"]'); 153 | if (!tab) return {}; 154 | var content = document.querySelector(tab.hash); 155 | 156 | // Hide the tab 157 | tab.setAttribute("aria-selected", "false"); 158 | 159 | // Hide the content 160 | if (!content) return { previousTab: tab }; 161 | content.setAttribute("hidden", "hidden"); 162 | 163 | // Return the hidden tab and content 164 | return { 165 | previousTab: tab, 166 | previousContent: content, 167 | }; 168 | }; 169 | 170 | /** 171 | * Show a tab and its content 172 | * @param {Node} tab The tab 173 | * @param {Node} content The tab content 174 | */ 175 | var show = function (tab, content) { 176 | tab.setAttribute("aria-selected", "true"); 177 | content.removeAttribute("hidden"); 178 | tab.focus(); 179 | }; 180 | 181 | /** 182 | * Toggle a new tab 183 | * @param {Node} tab The tab to show 184 | */ 185 | var toggle = function (tab) { 186 | // Make sure there's a tab to toggle and it's not already active 187 | if (!tab || tab.getAttribute("aria-selected") == "true") return; 188 | 189 | // Variables 190 | var content = document.querySelector(tab.hash); 191 | if (!content) return; 192 | 193 | // Hide active tab and content 194 | var details = hide(tab); 195 | 196 | // Show new tab and content 197 | show(tab, content); 198 | 199 | // Add event details 200 | details.tab = tab; 201 | details.content = content; 202 | 203 | // Emit a custom event 204 | emitEvent(tab, details); 205 | }; 206 | 207 | /** 208 | * Get all of the tabs in a tablist 209 | * @param {Node} tab A tab from the list 210 | * @return {Object} The tabs and the index of the currently active one 211 | */ 212 | var getTabsMap = function (tab) { 213 | var tabGroup = tab.closest('[role="tablist"]'); 214 | var tabs = tabGroup ? tabGroup.querySelectorAll('[role="tab"]') : null; 215 | if (!tabs) return; 216 | return { 217 | tabs: tabs, 218 | index: Array.prototype.indexOf.call(tabs, tab), 219 | }; 220 | }; 221 | 222 | /** 223 | * Switch the active tab based on keyboard activity 224 | * @param {Node} tab The currently active tab 225 | * @param {Key} key The key that was pressed 226 | */ 227 | var switchTabs = function (tab, key) { 228 | // Get a map of tabs 229 | var map = getTabsMap(tab); 230 | if (!map) return; 231 | var length = map.tabs.length - 1; 232 | var index; 233 | 234 | // Go to previous tab 235 | if (["ArrowUp", "ArrowLeft", "Up", "Left"].indexOf(key) > -1) { 236 | index = map.index < 1 ? length : map.index - 1; 237 | } 238 | 239 | // Go to next tab 240 | else if (["ArrowDown", "ArrowRight", "Down", "Right"].indexOf(key) > -1) { 241 | index = map.index === length ? 0 : map.index + 1; 242 | } 243 | 244 | // Go to home 245 | else if (key === "Home") { 246 | index = 0; 247 | } 248 | 249 | // Go to end 250 | else if (key === "End") { 251 | index = length; 252 | } 253 | 254 | // Toggle the tab 255 | toggle(map.tabs[index]); 256 | }; 257 | 258 | /** 259 | * Create the Constructor object 260 | */ 261 | var Constructor = function (selector, options) { 262 | // 263 | // Variables 264 | // 265 | 266 | var publicAPIs = {}; 267 | var settings, tabWrapper; 268 | 269 | // 270 | // Methods 271 | // 272 | 273 | publicAPIs.destroy = function () { 274 | // Get all tabs 275 | var tabs = tabWrapper.querySelectorAll("a"); 276 | 277 | // Add roles to tabs 278 | Array.prototype.forEach.call(tabs, function (tab) { 279 | // Get the tab content 280 | var content = document.querySelector(tab.hash); 281 | if (!content) return; 282 | 283 | // Setup the tab 284 | destroyTab(tab, content, settings); 285 | }); 286 | 287 | // Remove role from wrapper 288 | tabWrapper.removeAttribute("role"); 289 | 290 | // Remove event listeners 291 | document.documentElement.removeEventListener( 292 | "click", 293 | clickHandler, 294 | true 295 | ); 296 | tabWrapper.removeEventListener("keydown", keyHandler, true); 297 | 298 | // Reset variables 299 | settings = null; 300 | tabWrapper = null; 301 | }; 302 | 303 | /** 304 | * Setup the DOM with the proper attributes 305 | */ 306 | publicAPIs.setup = function () { 307 | // Variables 308 | tabWrapper = document.querySelector(selector); 309 | if (!tabWrapper) return; 310 | var tabs = tabWrapper.querySelectorAll("a"); 311 | 312 | // Add role to wrapper 313 | tabWrapper.setAttribute("role", "tablist"); 314 | 315 | // Add roles to tabs. provide dynanmic tab indexes if we are within reveal 316 | var contentTabindexes = 317 | window.document.body.classList.contains("reveal-viewport"); 318 | var nextTabindex = 1; 319 | Array.prototype.forEach.call(tabs, function (tab) { 320 | if (contentTabindexes) { 321 | tab.setAttribute("tabindex", "" + nextTabindex++); 322 | } else { 323 | tab.setAttribute("tabindex", "0"); 324 | } 325 | 326 | // Get the tab content 327 | var content = document.querySelector(tab.hash); 328 | if (!content) return; 329 | 330 | // set tab indexes for content 331 | if (contentTabindexes) { 332 | getKeyboardFocusableElements(content).forEach(function (el) { 333 | el.setAttribute("tabindex", "" + nextTabindex++); 334 | }); 335 | } 336 | 337 | // Setup the tab 338 | setupTab(tab, content, settings); 339 | }); 340 | }; 341 | 342 | /** 343 | * Toggle a tab based on an ID 344 | * @param {String|Node} id The tab to toggle 345 | */ 346 | publicAPIs.toggle = function (id) { 347 | // Get the tab 348 | var tab = id; 349 | if (typeof id === "string") { 350 | tab = document.querySelector( 351 | selector + ' [role="tab"][href*="' + id + '"]' 352 | ); 353 | } 354 | 355 | // Toggle the tab 356 | toggle(tab); 357 | }; 358 | 359 | /** 360 | * Handle click events 361 | */ 362 | var clickHandler = function (event) { 363 | // Only run on toggles 364 | var tab = event.target.closest(selector + ' [role="tab"]'); 365 | if (!tab) return; 366 | 367 | // Prevent link behavior 368 | event.preventDefault(); 369 | 370 | // Toggle the tab 371 | toggle(tab); 372 | }; 373 | 374 | /** 375 | * Handle keydown events 376 | */ 377 | var keyHandler = function (event) { 378 | // Only run if a tab is in focus 379 | var tab = document.activeElement; 380 | if (!tab.matches(selector + ' [role="tab"]')) return; 381 | 382 | // Only run for specific keys 383 | if (["Home", "End"].indexOf(event.key) < 0) return; 384 | 385 | // Switch tabs 386 | switchTabs(tab, event.key); 387 | }; 388 | 389 | /** 390 | * Initialize the instance 391 | */ 392 | var init = function () { 393 | // Merge user options with defaults 394 | settings = extend(defaults, options || {}); 395 | 396 | // Setup the DOM 397 | publicAPIs.setup(); 398 | 399 | // Add event listeners 400 | document.documentElement.addEventListener("click", clickHandler, true); 401 | tabWrapper.addEventListener("keydown", keyHandler, true); 402 | }; 403 | 404 | // 405 | // Initialize and return the Public APIs 406 | // 407 | 408 | init(); 409 | return publicAPIs; 410 | }; 411 | 412 | // 413 | // Return the Constructor 414 | // 415 | 416 | return Constructor; 417 | } 418 | ); 419 | -------------------------------------------------------------------------------- /docs/site_libs/quarto-html/tippy.css: -------------------------------------------------------------------------------- 1 | .tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1} -------------------------------------------------------------------------------- /docs/site_libs/quarto-nav/quarto-nav.js: -------------------------------------------------------------------------------- 1 | const headroomChanged = new CustomEvent("quarto-hrChanged", { 2 | detail: {}, 3 | bubbles: true, 4 | cancelable: false, 5 | composed: false, 6 | }); 7 | 8 | window.document.addEventListener("DOMContentLoaded", function () { 9 | let init = false; 10 | 11 | function throttle(func, wait) { 12 | var timeout; 13 | return function () { 14 | const context = this; 15 | const args = arguments; 16 | const later = function () { 17 | clearTimeout(timeout); 18 | timeout = null; 19 | func.apply(context, args); 20 | }; 21 | 22 | if (!timeout) { 23 | timeout = setTimeout(later, wait); 24 | } 25 | }; 26 | } 27 | 28 | function headerOffset() { 29 | // Set an offset if there is are fixed top navbar 30 | const headerEl = window.document.querySelector("header.fixed-top"); 31 | if (headerEl) { 32 | return headerEl.clientHeight; 33 | } else { 34 | return 0; 35 | } 36 | } 37 | 38 | function footerOffset() { 39 | const footerEl = window.document.querySelector("footer.footer"); 40 | if (footerEl) { 41 | return footerEl.clientHeight; 42 | } else { 43 | return 0; 44 | } 45 | } 46 | 47 | function updateDocumentOffsetWithoutAnimation() { 48 | updateDocumentOffset(false); 49 | } 50 | 51 | function updateDocumentOffset(animated) { 52 | // set body offset 53 | const topOffset = headerOffset(); 54 | const bodyOffset = topOffset + footerOffset(); 55 | const bodyEl = window.document.body; 56 | bodyEl.setAttribute("data-bs-offset", topOffset); 57 | bodyEl.style.paddingTop = topOffset + "px"; 58 | 59 | // deal with sidebar offsets 60 | const sidebars = window.document.querySelectorAll( 61 | ".sidebar, .headroom-target" 62 | ); 63 | sidebars.forEach((sidebar) => { 64 | if (!animated) { 65 | sidebar.classList.add("notransition"); 66 | // Remove the no transition class after the animation has time to complete 67 | setTimeout(function () { 68 | sidebar.classList.remove("notransition"); 69 | }, 201); 70 | } 71 | 72 | if (window.Headroom && sidebar.classList.contains("sidebar-unpinned")) { 73 | sidebar.style.top = "0"; 74 | sidebar.style.maxHeight = "100vh"; 75 | } else { 76 | sidebar.style.top = topOffset + "px"; 77 | sidebar.style.maxHeight = "calc(100vh - " + topOffset + "px)"; 78 | } 79 | }); 80 | 81 | // allow space for footer 82 | const mainContainer = window.document.querySelector(".quarto-container"); 83 | if (mainContainer) { 84 | mainContainer.style.minHeight = "calc(100vh - " + bodyOffset + "px)"; 85 | } 86 | 87 | // link offset 88 | let linkStyle = window.document.querySelector("#quarto-target-style"); 89 | if (!linkStyle) { 90 | linkStyle = window.document.createElement("style"); 91 | window.document.head.appendChild(linkStyle); 92 | } 93 | while (linkStyle.firstChild) { 94 | linkStyle.removeChild(linkStyle.firstChild); 95 | } 96 | if (topOffset > 0) { 97 | linkStyle.appendChild( 98 | window.document.createTextNode(` 99 | section:target::before { 100 | content: ""; 101 | display: block; 102 | height: ${topOffset}px; 103 | margin: -${topOffset}px 0 0; 104 | }`) 105 | ); 106 | } 107 | if (init) { 108 | window.dispatchEvent(headroomChanged); 109 | } 110 | init = true; 111 | } 112 | 113 | // initialize headroom 114 | var header = window.document.querySelector("#quarto-header"); 115 | if (header && window.Headroom) { 116 | const headroom = new window.Headroom(header, { 117 | tolerance: 5, 118 | onPin: function () { 119 | const sidebars = window.document.querySelectorAll( 120 | ".sidebar, .headroom-target" 121 | ); 122 | sidebars.forEach((sidebar) => { 123 | sidebar.classList.remove("sidebar-unpinned"); 124 | }); 125 | updateDocumentOffset(); 126 | }, 127 | onUnpin: function () { 128 | const sidebars = window.document.querySelectorAll( 129 | ".sidebar, .headroom-target" 130 | ); 131 | sidebars.forEach((sidebar) => { 132 | sidebar.classList.add("sidebar-unpinned"); 133 | }); 134 | updateDocumentOffset(); 135 | }, 136 | }); 137 | headroom.init(); 138 | 139 | let frozen = false; 140 | window.quartoToggleHeadroom = function () { 141 | if (frozen) { 142 | headroom.unfreeze(); 143 | frozen = false; 144 | } else { 145 | headroom.freeze(); 146 | frozen = true; 147 | } 148 | }; 149 | } 150 | 151 | // Observe size changed for the header 152 | const headerEl = window.document.querySelector("header.fixed-top"); 153 | if (headerEl && window.ResizeObserver) { 154 | const observer = new window.ResizeObserver( 155 | throttle(updateDocumentOffsetWithoutAnimation, 50) 156 | ); 157 | observer.observe(headerEl, { 158 | attributes: true, 159 | childList: true, 160 | characterData: true, 161 | }); 162 | } else { 163 | window.addEventListener( 164 | "resize", 165 | throttle(updateDocumentOffsetWithoutAnimation, 50) 166 | ); 167 | setTimeout(updateDocumentOffsetWithoutAnimation, 500); 168 | } 169 | 170 | // fixup index.html links if we aren't on the filesystem 171 | if (window.location.protocol !== "file:") { 172 | const links = window.document.querySelectorAll("a"); 173 | for (let i = 0; i < links.length; i++) { 174 | links[i].href = links[i].href.replace(/\/index\.html/, "/"); 175 | } 176 | 177 | // Fixup any sharing links that require urls 178 | // Append url to any sharing urls 179 | const sharingLinks = window.document.querySelectorAll( 180 | "a.sidebar-tools-main-item" 181 | ); 182 | for (let i = 0; i < sharingLinks.length; i++) { 183 | const sharingLink = sharingLinks[i]; 184 | const href = sharingLink.getAttribute("href"); 185 | if (href) { 186 | sharingLink.setAttribute( 187 | "href", 188 | href.replace("|url|", window.location.href) 189 | ); 190 | } 191 | } 192 | 193 | // Scroll the active navigation item into view, if necessary 194 | const navSidebars = window.document.querySelectorAll( 195 | "div#quarto-sidebar > nav" 196 | ); 197 | if (navSidebars.length === 1) { 198 | // Find the active item 199 | const targetNode = navSidebars[0]; 200 | const activeItems = window.document.querySelectorAll( 201 | "li.sidebar-item a.active" 202 | ); 203 | const activeItem = activeItems[0]; 204 | 205 | if (activeItems.length === 1) { 206 | // Wait for the scroll height and height to resolve by observing size changes on the 207 | // nav element that is scrollable 208 | const resizeObserver = new ResizeObserver((_entries) => { 209 | // The bottom of the element 210 | const elBottom = activeItem.offsetTop; 211 | const viewBottom = targetNode.scrollTop + targetNode.clientHeight; 212 | 213 | // The element height and scroll height are the same, then we are still loading 214 | if (viewBottom !== targetNode.scrollHeight) { 215 | // Determine if the item isn't visible and scroll to it 216 | if (elBottom >= viewBottom) { 217 | targetNode.scrollTop = elBottom; 218 | } 219 | 220 | // stop observing now since we've completed the scroll 221 | resizeObserver.unobserve(targetNode); 222 | } 223 | }); 224 | resizeObserver.observe(targetNode); 225 | } 226 | } 227 | } 228 | }); 229 | -------------------------------------------------------------------------------- /docs/site_libs/revealjs/dist/reset.css: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v4.0 | 20180602 3 | License: none (public domain) 4 | */ 5 | 6 | html, body, div, span, applet, object, iframe, 7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 8 | a, abbr, acronym, address, big, cite, code, 9 | del, dfn, em, img, ins, kbd, q, s, samp, 10 | small, strike, strong, sub, sup, tt, var, 11 | b, u, i, center, 12 | dl, dt, dd, ol, ul, li, 13 | fieldset, form, label, legend, 14 | table, caption, tbody, tfoot, thead, tr, th, td, 15 | article, aside, canvas, details, embed, 16 | figure, figcaption, footer, header, hgroup, 17 | main, menu, nav, output, ruby, section, summary, 18 | time, mark, audio, video { 19 | margin: 0; 20 | padding: 0; 21 | border: 0; 22 | font-size: 100%; 23 | font: inherit; 24 | vertical-align: baseline; 25 | } 26 | /* HTML5 display-role reset for older browsers */ 27 | article, aside, details, figcaption, figure, 28 | footer, header, hgroup, main, menu, nav, section { 29 | display: block; 30 | } -------------------------------------------------------------------------------- /docs/site_libs/revealjs/dist/theme/fonts/league-gothic/LICENSE: -------------------------------------------------------------------------------- 1 | SIL Open Font License (OFL) 2 | http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL 3 | -------------------------------------------------------------------------------- /docs/site_libs/revealjs/dist/theme/fonts/league-gothic/league-gothic.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'League Gothic'; 3 | src: url('./league-gothic.eot'); 4 | src: url('./league-gothic.eot?#iefix') format('embedded-opentype'), 5 | url('./league-gothic.woff') format('woff'), 6 | url('./league-gothic.ttf') format('truetype'); 7 | 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | -------------------------------------------------------------------------------- /docs/site_libs/revealjs/dist/theme/fonts/league-gothic/league-gothic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/docs/site_libs/revealjs/dist/theme/fonts/league-gothic/league-gothic.eot -------------------------------------------------------------------------------- /docs/site_libs/revealjs/dist/theme/fonts/league-gothic/league-gothic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/docs/site_libs/revealjs/dist/theme/fonts/league-gothic/league-gothic.ttf -------------------------------------------------------------------------------- /docs/site_libs/revealjs/dist/theme/fonts/league-gothic/league-gothic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/docs/site_libs/revealjs/dist/theme/fonts/league-gothic/league-gothic.woff -------------------------------------------------------------------------------- /docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/LICENSE: -------------------------------------------------------------------------------- 1 | SIL Open Font License 2 | 3 | Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name ‘Source’. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. 4 | 5 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 6 | This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL 7 | 8 | —————————————————————————————- 9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 10 | —————————————————————————————- 11 | 12 | PREAMBLE 13 | The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. 14 | 15 | The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. 16 | 17 | DEFINITIONS 18 | “Font Software” refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. 19 | 20 | “Reserved Font Name” refers to any names specified as such after the copyright statement(s). 21 | 22 | “Original Version” refers to the collection of Font Software components as distributed by the Copyright Holder(s). 23 | 24 | “Modified Version” refers to any derivative made by adding to, deleting, or substituting—in part or in whole—any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. 25 | 26 | “Author” refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. 27 | 28 | PERMISSION & CONDITIONS 29 | Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: 30 | 31 | 1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. 32 | 33 | 2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. 34 | 35 | 3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. 36 | 37 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. 38 | 39 | 5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. 40 | 41 | TERMINATION 42 | This license becomes null and void if any of the above conditions are not met. 43 | 44 | DISCLAIMER 45 | THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. -------------------------------------------------------------------------------- /docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-italic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-italic.eot -------------------------------------------------------------------------------- /docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-italic.ttf -------------------------------------------------------------------------------- /docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-italic.woff -------------------------------------------------------------------------------- /docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-regular.eot -------------------------------------------------------------------------------- /docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-regular.ttf -------------------------------------------------------------------------------- /docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-regular.woff -------------------------------------------------------------------------------- /docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.eot -------------------------------------------------------------------------------- /docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.ttf -------------------------------------------------------------------------------- /docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-semibold.woff -------------------------------------------------------------------------------- /docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.eot -------------------------------------------------------------------------------- /docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.ttf -------------------------------------------------------------------------------- /docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro-semibolditalic.woff -------------------------------------------------------------------------------- /docs/site_libs/revealjs/dist/theme/fonts/source-sans-pro/source-sans-pro.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Source Sans Pro'; 3 | src: url('./source-sans-pro-regular.eot'); 4 | src: url('./source-sans-pro-regular.eot?#iefix') format('embedded-opentype'), 5 | url('./source-sans-pro-regular.woff') format('woff'), 6 | url('./source-sans-pro-regular.ttf') format('truetype'); 7 | font-weight: normal; 8 | font-style: normal; 9 | } 10 | 11 | @font-face { 12 | font-family: 'Source Sans Pro'; 13 | src: url('./source-sans-pro-italic.eot'); 14 | src: url('./source-sans-pro-italic.eot?#iefix') format('embedded-opentype'), 15 | url('./source-sans-pro-italic.woff') format('woff'), 16 | url('./source-sans-pro-italic.ttf') format('truetype'); 17 | font-weight: normal; 18 | font-style: italic; 19 | } 20 | 21 | @font-face { 22 | font-family: 'Source Sans Pro'; 23 | src: url('./source-sans-pro-semibold.eot'); 24 | src: url('./source-sans-pro-semibold.eot?#iefix') format('embedded-opentype'), 25 | url('./source-sans-pro-semibold.woff') format('woff'), 26 | url('./source-sans-pro-semibold.ttf') format('truetype'); 27 | font-weight: 600; 28 | font-style: normal; 29 | } 30 | 31 | @font-face { 32 | font-family: 'Source Sans Pro'; 33 | src: url('./source-sans-pro-semibolditalic.eot'); 34 | src: url('./source-sans-pro-semibolditalic.eot?#iefix') format('embedded-opentype'), 35 | url('./source-sans-pro-semibolditalic.woff') format('woff'), 36 | url('./source-sans-pro-semibolditalic.ttf') format('truetype'); 37 | font-weight: 600; 38 | font-style: italic; 39 | } 40 | -------------------------------------------------------------------------------- /docs/site_libs/revealjs/plugin/highlight/monokai.css: -------------------------------------------------------------------------------- 1 | /* 2 | Monokai style - ported by Luigi Maselli - http://grigio.org 3 | */ 4 | 5 | .hljs { 6 | display: block; 7 | overflow-x: auto; 8 | padding: 0.5em; 9 | background: #272822; 10 | color: #ddd; 11 | } 12 | 13 | .hljs-tag, 14 | .hljs-keyword, 15 | .hljs-selector-tag, 16 | .hljs-literal, 17 | .hljs-strong, 18 | .hljs-name { 19 | color: #f92672; 20 | } 21 | 22 | .hljs-code { 23 | color: #66d9ef; 24 | } 25 | 26 | .hljs-class .hljs-title { 27 | color: white; 28 | } 29 | 30 | .hljs-attribute, 31 | .hljs-symbol, 32 | .hljs-regexp, 33 | .hljs-link { 34 | color: #bf79db; 35 | } 36 | 37 | .hljs-string, 38 | .hljs-bullet, 39 | .hljs-subst, 40 | .hljs-title, 41 | .hljs-section, 42 | .hljs-emphasis, 43 | .hljs-type, 44 | .hljs-built_in, 45 | .hljs-builtin-name, 46 | .hljs-selector-attr, 47 | .hljs-selector-pseudo, 48 | .hljs-addition, 49 | .hljs-variable, 50 | .hljs-template-tag, 51 | .hljs-template-variable { 52 | color: #a6e22e; 53 | } 54 | 55 | .hljs-comment, 56 | .hljs-quote, 57 | .hljs-deletion, 58 | .hljs-meta { 59 | color: #75715e; 60 | } 61 | 62 | .hljs-keyword, 63 | .hljs-selector-tag, 64 | .hljs-literal, 65 | .hljs-doctag, 66 | .hljs-title, 67 | .hljs-section, 68 | .hljs-type, 69 | .hljs-selector-id { 70 | font-weight: bold; 71 | } 72 | -------------------------------------------------------------------------------- /docs/site_libs/revealjs/plugin/highlight/zenburn.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Zenburn style from voldmar.ru (c) Vladimir Epifanov 4 | based on dark.css by Ivan Sagalaev 5 | 6 | */ 7 | 8 | .hljs { 9 | display: block; 10 | overflow-x: auto; 11 | padding: 0.5em; 12 | background: #3f3f3f; 13 | color: #dcdcdc; 14 | } 15 | 16 | .hljs-keyword, 17 | .hljs-selector-tag, 18 | .hljs-tag { 19 | color: #e3ceab; 20 | } 21 | 22 | .hljs-template-tag { 23 | color: #dcdcdc; 24 | } 25 | 26 | .hljs-number { 27 | color: #8cd0d3; 28 | } 29 | 30 | .hljs-variable, 31 | .hljs-template-variable, 32 | .hljs-attribute { 33 | color: #efdcbc; 34 | } 35 | 36 | .hljs-literal { 37 | color: #efefaf; 38 | } 39 | 40 | .hljs-subst { 41 | color: #8f8f8f; 42 | } 43 | 44 | .hljs-title, 45 | .hljs-name, 46 | .hljs-selector-id, 47 | .hljs-selector-class, 48 | .hljs-section, 49 | .hljs-type { 50 | color: #efef8f; 51 | } 52 | 53 | .hljs-symbol, 54 | .hljs-bullet, 55 | .hljs-link { 56 | color: #dca3a3; 57 | } 58 | 59 | .hljs-deletion, 60 | .hljs-string, 61 | .hljs-built_in, 62 | .hljs-builtin-name { 63 | color: #cc9393; 64 | } 65 | 66 | .hljs-addition, 67 | .hljs-comment, 68 | .hljs-quote, 69 | .hljs-meta { 70 | color: #7f9f7f; 71 | } 72 | 73 | 74 | .hljs-emphasis { 75 | font-style: italic; 76 | } 77 | 78 | .hljs-strong { 79 | font-weight: bold; 80 | } 81 | -------------------------------------------------------------------------------- /docs/site_libs/revealjs/plugin/math/katex.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A plugin which enables rendering of math equations inside 3 | * of reveal.js slides. Essentially a thin wrapper for KaTeX. 4 | * 5 | * @author Hakim El Hattab 6 | * @author Gerhard Burger 7 | */ 8 | export const KaTeX = () => { 9 | let deck; 10 | 11 | let defaultOptions = { 12 | version: 'latest', 13 | delimiters: [ 14 | {left: '$$', right: '$$', display: true}, // Note: $$ has to come before $ 15 | {left: '$', right: '$', display: false}, 16 | {left: '\\(', right: '\\)', display: false}, 17 | {left: '\\[', right: '\\]', display: true} 18 | ], 19 | ignoredTags: ['script', 'noscript', 'style', 'textarea', 'pre'] 20 | } 21 | 22 | const loadCss = src => { 23 | let link = document.createElement('link'); 24 | link.rel = 'stylesheet'; 25 | link.href = src; 26 | document.head.appendChild(link); 27 | }; 28 | 29 | /** 30 | * Loads a JavaScript file and returns a Promise for when it is loaded 31 | * Credits: https://aaronsmith.online/easily-load-an-external-script-using-javascript/ 32 | */ 33 | const loadScript = src => { 34 | return new Promise((resolve, reject) => { 35 | const script = document.createElement('script') 36 | script.type = 'text/javascript' 37 | script.onload = resolve 38 | script.onerror = reject 39 | script.src = src 40 | document.head.append(script) 41 | }) 42 | }; 43 | 44 | async function loadScripts(urls) { 45 | for(const url of urls) { 46 | await loadScript(url); 47 | } 48 | } 49 | 50 | return { 51 | id: 'katex', 52 | 53 | init: function (reveal) { 54 | 55 | deck = reveal; 56 | 57 | let revealOptions = deck.getConfig().katex || {}; 58 | 59 | let options = {...defaultOptions, ...revealOptions}; 60 | const {local, version, extensions, ...katexOptions} = options; 61 | 62 | let baseUrl = options.local || 'https://cdn.jsdelivr.net/npm/katex'; 63 | let versionString = options.local ? '' : '@' + options.version; 64 | 65 | let cssUrl = baseUrl + versionString + '/dist/katex.min.css'; 66 | let katexUrl = baseUrl + versionString + '/dist/katex.min.js'; 67 | let mhchemUrl = baseUrl + versionString + '/dist/contrib/mhchem.min.js' 68 | let karUrl = baseUrl + versionString + '/dist/contrib/auto-render.min.js'; 69 | 70 | let katexScripts = [katexUrl]; 71 | if(options.extensions && options.extensions.includes("mhchem")) { 72 | katexScripts.push(mhchemUrl); 73 | } 74 | katexScripts.push(karUrl); 75 | 76 | const renderMath = () => { 77 | renderMathInElement(reveal.getSlidesElement(), katexOptions); 78 | deck.layout(); 79 | } 80 | 81 | loadCss(cssUrl); 82 | 83 | // For some reason dynamically loading with defer attribute doesn't result in the expected behavior, the below code does 84 | loadScripts(katexScripts).then(() => { 85 | if( deck.isReady() ) { 86 | renderMath(); 87 | } 88 | else { 89 | deck.on( 'ready', renderMath.bind( this ) ); 90 | } 91 | }); 92 | 93 | } 94 | } 95 | 96 | }; 97 | -------------------------------------------------------------------------------- /docs/site_libs/revealjs/plugin/math/mathjax2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A plugin which enables rendering of math equations inside 3 | * of reveal.js slides. Essentially a thin wrapper for MathJax. 4 | * 5 | * @author Hakim El Hattab 6 | */ 7 | export const MathJax2 = () => { 8 | 9 | // The reveal.js instance this plugin is attached to 10 | let deck; 11 | 12 | let defaultOptions = { 13 | messageStyle: 'none', 14 | tex2jax: { 15 | inlineMath: [ [ '$', '$' ], [ '\\(', '\\)' ] ], 16 | skipTags: [ 'script', 'noscript', 'style', 'textarea', 'pre' ] 17 | }, 18 | skipStartupTypeset: true 19 | }; 20 | 21 | function loadScript( url, callback ) { 22 | 23 | let head = document.querySelector( 'head' ); 24 | let script = document.createElement( 'script' ); 25 | script.type = 'text/javascript'; 26 | script.src = url; 27 | 28 | // Wrapper for callback to make sure it only fires once 29 | let finish = () => { 30 | if( typeof callback === 'function' ) { 31 | callback.call(); 32 | callback = null; 33 | } 34 | } 35 | 36 | script.onload = finish; 37 | 38 | // IE 39 | script.onreadystatechange = () => { 40 | if ( this.readyState === 'loaded' ) { 41 | finish(); 42 | } 43 | } 44 | 45 | // Normal browsers 46 | head.appendChild( script ); 47 | 48 | } 49 | 50 | return { 51 | id: 'mathjax2', 52 | 53 | init: function( reveal ) { 54 | 55 | deck = reveal; 56 | 57 | let revealOptions = deck.getConfig().mathjax2 || deck.getConfig().math || {}; 58 | 59 | let options = { ...defaultOptions, ...revealOptions }; 60 | let mathjax = options.mathjax || 'https://cdn.jsdelivr.net/npm/mathjax@2/MathJax.js'; 61 | let config = options.config || 'TeX-AMS_HTML-full'; 62 | let url = mathjax + '?config=' + config; 63 | 64 | options.tex2jax = { ...defaultOptions.tex2jax, ...revealOptions.tex2jax }; 65 | 66 | options.mathjax = options.config = null; 67 | 68 | loadScript( url, function() { 69 | 70 | MathJax.Hub.Config( options ); 71 | 72 | // Typeset followed by an immediate reveal.js layout since 73 | // the typesetting process could affect slide height 74 | MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, deck.getRevealElement() ] ); 75 | MathJax.Hub.Queue( deck.layout ); 76 | 77 | // Reprocess equations in slides when they turn visible 78 | deck.on( 'slidechanged', function( event ) { 79 | 80 | MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] ); 81 | 82 | } ); 83 | 84 | } ); 85 | 86 | } 87 | } 88 | 89 | }; 90 | -------------------------------------------------------------------------------- /docs/site_libs/revealjs/plugin/math/mathjax3.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A plugin which enables rendering of math equations inside 3 | * of reveal.js slides. Essentially a thin wrapper for MathJax 3 4 | * 5 | * @author Hakim El Hattab 6 | * @author Gerhard Burger 7 | */ 8 | export const MathJax3 = () => { 9 | 10 | // The reveal.js instance this plugin is attached to 11 | let deck; 12 | 13 | let defaultOptions = { 14 | tex: { 15 | inlineMath: [ [ '$', '$' ], [ '\\(', '\\)' ] ] 16 | }, 17 | options: { 18 | skipHtmlTags: [ 'script', 'noscript', 'style', 'textarea', 'pre' ] 19 | }, 20 | startup: { 21 | ready: () => { 22 | MathJax.startup.defaultReady(); 23 | MathJax.startup.promise.then(() => { 24 | Reveal.layout(); 25 | }); 26 | } 27 | } 28 | }; 29 | 30 | function loadScript( url, callback ) { 31 | 32 | let script = document.createElement( 'script' ); 33 | script.type = "text/javascript" 34 | script.id = "MathJax-script" 35 | script.src = url; 36 | script.async = true 37 | 38 | // Wrapper for callback to make sure it only fires once 39 | script.onload = () => { 40 | if (typeof callback === 'function') { 41 | callback.call(); 42 | callback = null; 43 | } 44 | }; 45 | 46 | document.head.appendChild( script ); 47 | 48 | } 49 | 50 | return { 51 | id: 'mathjax3', 52 | init: function(reveal) { 53 | 54 | deck = reveal; 55 | 56 | let revealOptions = deck.getConfig().mathjax3 || {}; 57 | let options = {...defaultOptions, ...revealOptions}; 58 | options.tex = {...defaultOptions.tex, ...revealOptions.tex} 59 | options.options = {...options.options, ...defaultOptions.options} 60 | options.startup = {...defaultOptions.startup, ...revealOptions.startup} 61 | 62 | let url = options.mathjax || 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js'; 63 | options.mathjax = null; 64 | 65 | window.MathJax = options; 66 | 67 | loadScript( url, function() { 68 | // Reprocess equations in slides when they turn visible 69 | Reveal.addEventListener( 'slidechanged', function( event ) { 70 | MathJax.typeset(); 71 | } ); 72 | } ); 73 | 74 | } 75 | } 76 | 77 | }; 78 | -------------------------------------------------------------------------------- /docs/site_libs/revealjs/plugin/math/plugin.js: -------------------------------------------------------------------------------- 1 | import {KaTeX} from "./katex"; 2 | import {MathJax2} from "./mathjax2"; 3 | import {MathJax3} from "./mathjax3"; 4 | 5 | const defaultTypesetter = MathJax2; 6 | 7 | /*! 8 | * This plugin is a wrapper for the MathJax2, 9 | * MathJax3 and KaTeX typesetter plugins. 10 | */ 11 | export default Plugin = Object.assign( defaultTypesetter(), { 12 | KaTeX, 13 | MathJax2, 14 | MathJax3 15 | } ); -------------------------------------------------------------------------------- /docs/site_libs/revealjs/plugin/notes/plugin.js: -------------------------------------------------------------------------------- 1 | import speakerViewHTML from './speaker-view.html'; 2 | 3 | import marked from 'marked'; 4 | 5 | /** 6 | * Handles opening of and synchronization with the reveal.js 7 | * notes window. 8 | * 9 | * Handshake process: 10 | * 1. This window posts 'connect' to notes window 11 | * - Includes URL of presentation to show 12 | * 2. Notes window responds with 'connected' when it is available 13 | * 3. This window proceeds to send the current presentation state 14 | * to the notes window 15 | */ 16 | const Plugin = () => { 17 | 18 | let popup = null; 19 | 20 | let deck; 21 | 22 | function openNotes() { 23 | 24 | if (popup && !popup.closed) { 25 | popup.focus(); 26 | return; 27 | } 28 | 29 | popup = window.open( 'about:blank', 'reveal.js - Notes', 'width=1100,height=700' ); 30 | popup.marked = marked; 31 | popup.document.write( speakerViewHTML ); 32 | 33 | if( !popup ) { 34 | alert( 'Speaker view popup failed to open. Please make sure popups are allowed and reopen the speaker view.' ); 35 | return; 36 | } 37 | 38 | /** 39 | * Connect to the notes window through a postmessage handshake. 40 | * Using postmessage enables us to work in situations where the 41 | * origins differ, such as a presentation being opened from the 42 | * file system. 43 | */ 44 | function connect() { 45 | // Keep trying to connect until we get a 'connected' message back 46 | let connectInterval = setInterval( function() { 47 | popup.postMessage( JSON.stringify( { 48 | namespace: 'reveal-notes', 49 | type: 'connect', 50 | url: window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search, 51 | state: deck.getState() 52 | } ), '*' ); 53 | }, 500 ); 54 | 55 | window.addEventListener( 'message', function( event ) { 56 | let data = JSON.parse( event.data ); 57 | if( data && data.namespace === 'reveal-notes' && data.type === 'connected' ) { 58 | clearInterval( connectInterval ); 59 | onConnected(); 60 | } 61 | if( data && data.namespace === 'reveal-notes' && data.type === 'call' ) { 62 | callRevealApi( data.methodName, data.arguments, data.callId ); 63 | } 64 | } ); 65 | } 66 | 67 | /** 68 | * Calls the specified Reveal.js method with the provided argument 69 | * and then pushes the result to the notes frame. 70 | */ 71 | function callRevealApi( methodName, methodArguments, callId ) { 72 | 73 | let result = deck[methodName].apply( deck, methodArguments ); 74 | popup.postMessage( JSON.stringify( { 75 | namespace: 'reveal-notes', 76 | type: 'return', 77 | result: result, 78 | callId: callId 79 | } ), '*' ); 80 | 81 | } 82 | 83 | /** 84 | * Posts the current slide data to the notes window 85 | */ 86 | function post( event ) { 87 | 88 | let slideElement = deck.getCurrentSlide(), 89 | notesElement = slideElement.querySelector( 'aside.notes' ), 90 | fragmentElement = slideElement.querySelector( '.current-fragment' ); 91 | 92 | let messageData = { 93 | namespace: 'reveal-notes', 94 | type: 'state', 95 | notes: '', 96 | markdown: false, 97 | whitespace: 'normal', 98 | state: deck.getState() 99 | }; 100 | 101 | // Look for notes defined in a slide attribute 102 | if( slideElement.hasAttribute( 'data-notes' ) ) { 103 | messageData.notes = slideElement.getAttribute( 'data-notes' ); 104 | messageData.whitespace = 'pre-wrap'; 105 | } 106 | 107 | // Look for notes defined in a fragment 108 | if( fragmentElement ) { 109 | let fragmentNotes = fragmentElement.querySelector( 'aside.notes' ); 110 | if( fragmentNotes ) { 111 | notesElement = fragmentNotes; 112 | } 113 | else if( fragmentElement.hasAttribute( 'data-notes' ) ) { 114 | messageData.notes = fragmentElement.getAttribute( 'data-notes' ); 115 | messageData.whitespace = 'pre-wrap'; 116 | 117 | // In case there are slide notes 118 | notesElement = null; 119 | } 120 | } 121 | 122 | // Look for notes defined in an aside element 123 | if( notesElement ) { 124 | messageData.notes = notesElement.innerHTML; 125 | messageData.markdown = typeof notesElement.getAttribute( 'data-markdown' ) === 'string'; 126 | } 127 | 128 | popup.postMessage( JSON.stringify( messageData ), '*' ); 129 | 130 | } 131 | 132 | /** 133 | * Called once we have established a connection to the notes 134 | * window. 135 | */ 136 | function onConnected() { 137 | 138 | // Monitor events that trigger a change in state 139 | deck.on( 'slidechanged', post ); 140 | deck.on( 'fragmentshown', post ); 141 | deck.on( 'fragmenthidden', post ); 142 | deck.on( 'overviewhidden', post ); 143 | deck.on( 'overviewshown', post ); 144 | deck.on( 'paused', post ); 145 | deck.on( 'resumed', post ); 146 | 147 | // Post the initial state 148 | post(); 149 | 150 | } 151 | 152 | connect(); 153 | 154 | } 155 | 156 | return { 157 | id: 'notes', 158 | 159 | init: function( reveal ) { 160 | 161 | deck = reveal; 162 | 163 | if( !/receiver/i.test( window.location.search ) ) { 164 | 165 | // If the there's a 'notes' query set, open directly 166 | if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) { 167 | openNotes(); 168 | } 169 | 170 | // Open the notes when the 's' key is hit 171 | deck.addKeyBinding({keyCode: 83, key: 'S', description: 'Speaker notes view'}, function() { 172 | openNotes(); 173 | } ); 174 | 175 | } 176 | 177 | }, 178 | 179 | open: openNotes 180 | }; 181 | 182 | }; 183 | 184 | export default Plugin; 185 | -------------------------------------------------------------------------------- /docs/site_libs/revealjs/plugin/pdf-export/pdfexport.js: -------------------------------------------------------------------------------- 1 | var PdfExport = ( function( _Reveal ){ 2 | 3 | var Reveal = _Reveal; 4 | var setStylesheet = null; 5 | var installAltKeyBindings = null; 6 | 7 | function getRevealJsPath(){ 8 | var regex = /\b[^/]+\/reveal.css$/i; 9 | var script = Array.from( document.querySelectorAll( 'link' ) ).find( function( e ){ 10 | return e.attributes.href && e.attributes.href.value.search( regex ) >= 0; 11 | }); 12 | if( !script ){ 13 | console.error( 'reveal.css could not be found in included elements. Did you rename this file?' ); 14 | return ''; 15 | } 16 | return script.attributes.href.value.replace( regex, '' ); 17 | } 18 | 19 | function setStylesheet3( pdfExport ){ 20 | var link = document.querySelector( '#print' ); 21 | if( !link ){ 22 | link = document.createElement( 'link' ); 23 | link.rel = 'stylesheet'; 24 | link.id = 'print'; 25 | document.querySelector( 'head' ).appendChild( link ); 26 | } 27 | var style = 'paper'; 28 | if( pdfExport ){ 29 | style = 'pdf'; 30 | } 31 | link.href = getRevealJsPath() + 'css/print/' + style + '.css'; 32 | } 33 | 34 | function setStylesheet4( pdfExport ){ 35 | } 36 | 37 | function installAltKeyBindings3(){ 38 | } 39 | 40 | function installAltKeyBindings4(){ 41 | if( isPrintingPDF() ){ 42 | var config = Reveal.getConfig(); 43 | var shortcut = config.pdfExportShortcut || 'E'; 44 | window.addEventListener( 'keydown', function( e ){ 45 | if( e.target.nodeName.toUpperCase() == 'BODY' 46 | && ( e.key.toUpperCase() == shortcut.toUpperCase() || e.keyCode == shortcut.toUpperCase().charCodeAt( 0 ) ) ){ 47 | e.preventDefault(); 48 | togglePdfExport(); 49 | return false; 50 | } 51 | }, true ); 52 | } 53 | } 54 | 55 | function isPrintingPDF(){ 56 | return ( /print-pdf/gi ).test( window.location.search ); 57 | } 58 | 59 | function togglePdfExport(){ 60 | var url_doc = new URL( document.URL ); 61 | var query_doc = new URLSearchParams( url_doc.searchParams ); 62 | if( isPrintingPDF() ){ 63 | query_doc.delete( 'print-pdf' ); 64 | }else{ 65 | query_doc.set( 'print-pdf', '' ); 66 | } 67 | url_doc.search = ( query_doc.toString() ? '?' + query_doc.toString() : '' ); 68 | window.location.href = url_doc.toString(); 69 | } 70 | 71 | function installKeyBindings(){ 72 | var config = Reveal.getConfig(); 73 | var shortcut = config.pdfExportShortcut || 'E'; 74 | Reveal.addKeyBinding({ 75 | keyCode: shortcut.toUpperCase().charCodeAt( 0 ), 76 | key: shortcut.toUpperCase(), 77 | description: 'PDF export mode' 78 | }, togglePdfExport ); 79 | installAltKeyBindings(); 80 | } 81 | 82 | function install(){ 83 | installKeyBindings(); 84 | setStylesheet( isPrintingPDF() ); 85 | } 86 | 87 | var Plugin = { 88 | } 89 | 90 | if( Reveal && Reveal.VERSION && Reveal.VERSION.length && Reveal.VERSION[ 0 ] == '3' ){ 91 | // reveal 3.x 92 | setStylesheet = setStylesheet3; 93 | installAltKeyBindings = installAltKeyBindings3; 94 | install(); 95 | }else{ 96 | // must be reveal 4.x 97 | setStylesheet = setStylesheet4; 98 | installAltKeyBindings = installAltKeyBindings4; 99 | Plugin.id = 'pdf-export'; 100 | Plugin.init = function( _Reveal ){ 101 | Reveal = _Reveal; 102 | install(); 103 | }; 104 | } 105 | 106 | return Plugin; 107 | 108 | })( Reveal ); 109 | -------------------------------------------------------------------------------- /docs/site_libs/revealjs/plugin/pdf-export/plugin.yml: -------------------------------------------------------------------------------- 1 | name: PdfExport 2 | script: pdfexport.js 3 | -------------------------------------------------------------------------------- /docs/site_libs/revealjs/plugin/quarto-line-highlight/line-highlight.css: -------------------------------------------------------------------------------- 1 | .reveal 2 | div.sourceCode 3 | pre 4 | code.has-line-highlights 5 | > span:not(.highlight-line) { 6 | opacity: 0.4; 7 | } 8 | 9 | .reveal pre.numberSource { 10 | padding-left: 0; 11 | } 12 | 13 | .reveal pre.numberSource code > span { 14 | left: -2.1em; 15 | } 16 | 17 | pre.numberSource code > span > a:first-child::before { 18 | left: -0.7em; 19 | } 20 | 21 | .reveal pre > code:not(:first-child).fragment { 22 | position: absolute; 23 | top: 0; 24 | left: 0; 25 | width: 100%; 26 | box-sizing: border-box; 27 | } 28 | 29 | .reveal div.sourceCode pre code { 30 | min-height: 100%; 31 | } 32 | -------------------------------------------------------------------------------- /docs/site_libs/revealjs/plugin/quarto-line-highlight/line-highlight.js: -------------------------------------------------------------------------------- 1 | window.QuartoLineHighlight = function () { 2 | function isPrintView() { 3 | return /print-pdf/gi.test(window.location.search); 4 | } 5 | 6 | const delimiters = { 7 | step: "|", 8 | line: ",", 9 | lineRange: "-", 10 | }; 11 | 12 | const regex = new RegExp( 13 | "^[\\d" + Object.values(delimiters).join("") + "]+$" 14 | ); 15 | 16 | function handleLinesSelector(deck, attr) { 17 | // if we are in printview with pdfSeparateFragments: false 18 | // then we'll also want to supress 19 | if (regex.test(attr)) { 20 | if (isPrintView() && deck.getConfig().pdfSeparateFragments !== true) { 21 | return false; 22 | } else { 23 | return true; 24 | } 25 | } else { 26 | return false; 27 | } 28 | } 29 | 30 | const kCodeLineNumbersAttr = "data-code-line-numbers"; 31 | const kFragmentIndex = "data-fragment-index"; 32 | 33 | function initQuartoLineHighlight(deck) { 34 | const divSourceCode = deck 35 | .getRevealElement() 36 | .querySelectorAll("div.sourceCode"); 37 | // Process each div created by Pandoc highlighting - numbered line are already included. 38 | divSourceCode.forEach((el) => { 39 | if (el.hasAttribute(kCodeLineNumbersAttr)) { 40 | const codeLineAttr = el.getAttribute(kCodeLineNumbersAttr); 41 | el.removeAttribute("data-code-line-numbers"); 42 | if (handleLinesSelector(deck, codeLineAttr)) { 43 | // Only process if attr is a string to select lines to highlights 44 | // e.g "1|3,6|8-11" 45 | const codeBlock = el.querySelectorAll("pre code"); 46 | codeBlock.forEach((code) => { 47 | // move attributes on code block 48 | code.setAttribute(kCodeLineNumbersAttr, codeLineAttr); 49 | 50 | const scrollState = { currentBlock: code }; 51 | 52 | // Check if there are steps and duplicate code block accordingly 53 | const highlightSteps = splitLineNumbers(codeLineAttr); 54 | if (highlightSteps.length > 1) { 55 | // If the original code block has a fragment-index, 56 | // each clone should follow in an incremental sequence 57 | let fragmentIndex = parseInt( 58 | code.getAttribute(kFragmentIndex), 59 | 10 60 | ); 61 | fragmentIndex = 62 | typeof fragmentIndex !== "number" || isNaN(fragmentIndex) 63 | ? null 64 | : fragmentIndex; 65 | 66 | let stepN = 1; 67 | highlightSteps.slice(1).forEach( 68 | // Generate fragments for all steps except the original block 69 | (step) => { 70 | var fragmentBlock = code.cloneNode(true); 71 | fragmentBlock.setAttribute( 72 | "data-code-line-numbers", 73 | joinLineNumbers([step]) 74 | ); 75 | fragmentBlock.classList.add("fragment"); 76 | 77 | // Pandoc sets id on spans we need to keep unique 78 | fragmentBlock 79 | .querySelectorAll(":scope > span") 80 | .forEach((span) => { 81 | if (span.hasAttribute("id")) { 82 | span.setAttribute( 83 | "id", 84 | span.getAttribute("id").concat("-" + stepN) 85 | ); 86 | } 87 | }); 88 | stepN = ++stepN; 89 | 90 | // Add duplicated element after existing one 91 | code.parentNode.appendChild(fragmentBlock); 92 | 93 | // Each new element is highlighted based on the new attributes value 94 | highlightCodeBlock(fragmentBlock); 95 | 96 | if (typeof fragmentIndex === "number") { 97 | fragmentBlock.setAttribute(kFragmentIndex, fragmentIndex); 98 | fragmentIndex += 1; 99 | } else { 100 | fragmentBlock.removeAttribute(kFragmentIndex); 101 | } 102 | 103 | // Scroll highlights into view as we step through them 104 | fragmentBlock.addEventListener( 105 | "visible", 106 | scrollHighlightedLineIntoView.bind( 107 | this, 108 | fragmentBlock, 109 | scrollState 110 | ) 111 | ); 112 | fragmentBlock.addEventListener( 113 | "hidden", 114 | scrollHighlightedLineIntoView.bind( 115 | this, 116 | fragmentBlock.previousSibling, 117 | scrollState 118 | ) 119 | ); 120 | } 121 | ); 122 | code.removeAttribute(kFragmentIndex); 123 | code.setAttribute( 124 | kCodeLineNumbersAttr, 125 | joinLineNumbers([highlightSteps[0]]) 126 | ); 127 | } 128 | 129 | // Scroll the first highlight into view when the slide becomes visible. 130 | const slide = 131 | typeof code.closest === "function" 132 | ? code.closest("section:not(.stack)") 133 | : null; 134 | if (slide) { 135 | const scrollFirstHighlightIntoView = function () { 136 | scrollHighlightedLineIntoView(code, scrollState, true); 137 | slide.removeEventListener( 138 | "visible", 139 | scrollFirstHighlightIntoView 140 | ); 141 | }; 142 | slide.addEventListener("visible", scrollFirstHighlightIntoView); 143 | } 144 | 145 | highlightCodeBlock(code); 146 | }); 147 | } 148 | } 149 | }); 150 | } 151 | 152 | function highlightCodeBlock(codeBlock) { 153 | const highlightSteps = splitLineNumbers( 154 | codeBlock.getAttribute(kCodeLineNumbersAttr) 155 | ); 156 | 157 | if (highlightSteps.length) { 158 | // If we have at least one step, we generate fragments 159 | highlightSteps[0].forEach((highlight) => { 160 | // Add expected class on
 for reveal CSS
161 |         codeBlock.parentNode.classList.add("code-wrapper");
162 | 
163 |         // Select lines to highlight
164 |         spanToHighlight = [];
165 |         if (typeof highlight.last === "number") {
166 |           spanToHighlight = [].slice.call(
167 |             codeBlock.querySelectorAll(
168 |               ":scope > span:nth-child(n+" +
169 |                 highlight.first +
170 |                 "):nth-child(-n+" +
171 |                 highlight.last +
172 |                 ")"
173 |             )
174 |           );
175 |         } else if (typeof highlight.first === "number") {
176 |           spanToHighlight = [].slice.call(
177 |             codeBlock.querySelectorAll(
178 |               ":scope > span:nth-child(" + highlight.first + ")"
179 |             )
180 |           );
181 |         }
182 |         if (spanToHighlight.length) {
183 |           // Add a class on  and  to select line to highlight
184 |           spanToHighlight.forEach((span) =>
185 |             span.classList.add("highlight-line")
186 |           );
187 |           codeBlock.classList.add("has-line-highlights");
188 |         }
189 |       });
190 |     }
191 |   }
192 | 
193 |   /**
194 |    * Animates scrolling to the first highlighted line
195 |    * in the given code block.
196 |    */
197 |   function scrollHighlightedLineIntoView(block, scrollState, skipAnimation) {
198 |     window.cancelAnimationFrame(scrollState.animationFrameID);
199 | 
200 |     // Match the scroll position of the currently visible
201 |     // code block
202 |     if (scrollState.currentBlock) {
203 |       block.scrollTop = scrollState.currentBlock.scrollTop;
204 |     }
205 | 
206 |     // Remember the current code block so that we can match
207 |     // its scroll position when showing/hiding fragments
208 |     scrollState.currentBlock = block;
209 | 
210 |     const highlightBounds = getHighlightedLineBounds(block);
211 |     let viewportHeight = block.offsetHeight;
212 | 
213 |     // Subtract padding from the viewport height
214 |     const blockStyles = window.getComputedStyle(block);
215 |     viewportHeight -=
216 |       parseInt(blockStyles.paddingTop) + parseInt(blockStyles.paddingBottom);
217 | 
218 |     // Scroll position which centers all highlights
219 |     const startTop = block.scrollTop;
220 |     let targetTop =
221 |       highlightBounds.top +
222 |       (Math.min(highlightBounds.bottom - highlightBounds.top, viewportHeight) -
223 |         viewportHeight) /
224 |         2;
225 | 
226 |     // Make sure the scroll target is within bounds
227 |     targetTop = Math.max(
228 |       Math.min(targetTop, block.scrollHeight - viewportHeight),
229 |       0
230 |     );
231 | 
232 |     if (skipAnimation === true || startTop === targetTop) {
233 |       block.scrollTop = targetTop;
234 |     } else {
235 |       // Don't attempt to scroll if there is no overflow
236 |       if (block.scrollHeight <= viewportHeight) return;
237 | 
238 |       let time = 0;
239 | 
240 |       const animate = function () {
241 |         time = Math.min(time + 0.02, 1);
242 | 
243 |         // Update our eased scroll position
244 |         block.scrollTop =
245 |           startTop + (targetTop - startTop) * easeInOutQuart(time);
246 | 
247 |         // Keep animating unless we've reached the end
248 |         if (time < 1) {
249 |           scrollState.animationFrameID = requestAnimationFrame(animate);
250 |         }
251 |       };
252 | 
253 |       animate();
254 |     }
255 |   }
256 | 
257 |   function getHighlightedLineBounds(block) {
258 |     const highlightedLines = block.querySelectorAll(".highlight-line");
259 |     if (highlightedLines.length === 0) {
260 |       return { top: 0, bottom: 0 };
261 |     } else {
262 |       const firstHighlight = highlightedLines[0];
263 |       const lastHighlight = highlightedLines[highlightedLines.length - 1];
264 | 
265 |       return {
266 |         top: firstHighlight.offsetTop,
267 |         bottom: lastHighlight.offsetTop + lastHighlight.offsetHeight,
268 |       };
269 |     }
270 |   }
271 | 
272 |   /**
273 |    * The easing function used when scrolling.
274 |    */
275 |   function easeInOutQuart(t) {
276 |     // easeInOutQuart
277 |     return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t;
278 |   }
279 | 
280 |   function splitLineNumbers(lineNumbersAttr) {
281 |     // remove space
282 |     lineNumbersAttr = lineNumbersAttr.replace("/s/g", "");
283 |     // seperate steps (for fragment)
284 |     lineNumbersAttr = lineNumbersAttr.split(delimiters.step);
285 | 
286 |     // for each step, calculate first and last line, if any
287 |     return lineNumbersAttr.map((highlights) => {
288 |       // detect lines
289 |       const lines = highlights.split(delimiters.line);
290 |       return lines.map((range) => {
291 |         if (/^[\d-]+$/.test(range)) {
292 |           range = range.split(delimiters.lineRange);
293 |           const firstLine = parseInt(range[0], 10);
294 |           const lastLine = range[1] ? parseInt(range[1], 10) : undefined;
295 |           return {
296 |             first: firstLine,
297 |             last: lastLine,
298 |           };
299 |         } else {
300 |           return {};
301 |         }
302 |       });
303 |     });
304 |   }
305 | 
306 |   function joinLineNumbers(splittedLineNumbers) {
307 |     return splittedLineNumbers
308 |       .map(function (highlights) {
309 |         return highlights
310 |           .map(function (highlight) {
311 |             // Line range
312 |             if (typeof highlight.last === "number") {
313 |               return highlight.first + delimiters.lineRange + highlight.last;
314 |             }
315 |             // Single line
316 |             else if (typeof highlight.first === "number") {
317 |               return highlight.first;
318 |             }
319 |             // All lines
320 |             else {
321 |               return "";
322 |             }
323 |           })
324 |           .join(delimiters.line);
325 |       })
326 |       .join(delimiters.step);
327 |   }
328 | 
329 |   return {
330 |     id: "quarto-line-highlight",
331 |     init: function (deck) {
332 |       initQuartoLineHighlight(deck);
333 | 
334 |       // If we're printing to PDF, scroll the code highlights of
335 |       // all blocks in the deck into view at once
336 |       deck.on("pdf-ready", function () {
337 |         [].slice
338 |           .call(
339 |             deck
340 |               .getRevealElement()
341 |               .querySelectorAll(
342 |                 "pre code[data-code-line-numbers].current-fragment"
343 |               )
344 |           )
345 |           .forEach(function (block) {
346 |             scrollHighlightedLineIntoView(block, {}, true);
347 |           });
348 |       });
349 |     },
350 |   };
351 | };
352 | 


--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/quarto-line-highlight/plugin.yml:
--------------------------------------------------------------------------------
1 | # adapted from https://github.com/hakimel/reveal.js/tree/master/plugin/highlight
2 | name: QuartoLineHighlight
3 | script: line-highlight.js
4 | stylesheet: line-highlight.css
5 | 


--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/quarto-support/footer.css:
--------------------------------------------------------------------------------
  1 | .reveal .slide-logo {
  2 |   display: block;
  3 |   position: fixed;
  4 |   bottom: 0;
  5 |   right: 12px;
  6 |   max-height: 2.2rem;
  7 |   width: auto;
  8 | }
  9 | 
 10 | .reveal .footer {
 11 |   display: block;
 12 |   position: fixed;
 13 |   bottom: 18px;
 14 |   width: 100%;
 15 |   margin: 0 auto;
 16 |   text-align: center;
 17 |   font-size: 18px;
 18 |   z-index: 2;
 19 | }
 20 | 
 21 | .reveal .footer > * {
 22 |   margin-top: 0;
 23 |   margin-bottom: 0;
 24 | }
 25 | 
 26 | .reveal .slide .footer {
 27 |   display: none;
 28 | }
 29 | 
 30 | .reveal .slide-number {
 31 |   bottom: 10px;
 32 |   right: 10px;
 33 |   font-size: 16px;
 34 |   background-color: transparent;
 35 | }
 36 | 
 37 | .reveal.has-logo .slide-number {
 38 |   bottom: initial;
 39 |   top: 8px;
 40 |   right: 8px;
 41 | }
 42 | 
 43 | .reveal .slide-number .slide-number-delimiter {
 44 |   margin: 0;
 45 | }
 46 | 
 47 | .reveal .slide-menu-button {
 48 |   left: 8px;
 49 |   bottom: 8px;
 50 | }
 51 | 
 52 | .reveal .slide-chalkboard-buttons {
 53 |   position: fixed;
 54 |   left: 12px;
 55 |   bottom: 8px;
 56 |   z-index: 30;
 57 |   font-size: 24px;
 58 | }
 59 | 
 60 | .reveal .slide-chalkboard-buttons.slide-menu-offset {
 61 |   left: 54px;
 62 | }
 63 | 
 64 | .reveal .slide-chalkboard-buttons > span {
 65 |   margin-right: 14px;
 66 |   cursor: pointer;
 67 | }
 68 | 
 69 | @media screen and (max-width: 800px) {
 70 |   .reveal .slide-logo {
 71 |     max-height: 1.1rem;
 72 |     bottom: -2px;
 73 |     right: 10px;
 74 |   }
 75 |   .reveal .footer {
 76 |     font-size: 14px;
 77 |     bottom: 12px;
 78 |   }
 79 |   .reveal .slide-number {
 80 |     font-size: 12px;
 81 |     bottom: 7px;
 82 |   }
 83 |   .reveal .slide-menu-button .fas::before {
 84 |     height: 1.3rem;
 85 |     width: 1.3rem;
 86 |     vertical-align: -0.125em;
 87 |     background-size: 1.3rem 1.3rem;
 88 |   }
 89 | 
 90 |   .reveal .slide-chalkboard-buttons .fas::before {
 91 |     height: 0.95rem;
 92 |     width: 0.95rem;
 93 |     background-size: 0.95rem 0.95rem;
 94 |     vertical-align: -0em;
 95 |   }
 96 | 
 97 |   .reveal .slide-chalkboard-buttons.slide-menu-offset {
 98 |     left: 36px;
 99 |   }
100 |   .reveal .slide-chalkboard-buttons > span {
101 |     margin-right: 9px;
102 |   }
103 | }
104 | 
105 | html.print-pdf .reveal .slide-menu-button,
106 | html.print-pdf .reveal .slide-chalkboard-buttons {
107 |   display: none;
108 | }
109 | 


--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/quarto-support/plugin.yml:
--------------------------------------------------------------------------------
1 | name: QuartoSupport
2 | script: support.js
3 | stylesheet: footer.css
4 | config:
5 |   smaller: false
6 | 


--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/quarto-support/support.js:
--------------------------------------------------------------------------------
  1 | // catch all plugin for various quarto features
  2 | window.QuartoSupport = function () {
  3 |   function isPrintView() {
  4 |     return /print-pdf/gi.test(window.location.search);
  5 |   }
  6 | 
  7 |   // implement controlsAudo
  8 |   function controlsAuto(deck) {
  9 |     const config = deck.getConfig();
 10 |     if (config.controlsAuto === true) {
 11 |       const iframe = window.location !== window.parent.location;
 12 |       const localhost =
 13 |         window.location.hostname === "localhost" ||
 14 |         window.location.hostname === "127.0.0.1";
 15 |       deck.configure({
 16 |         controls:
 17 |           (iframe && !localhost) ||
 18 |           (deck.hasVerticalSlides() && config.navigationMode !== "linear"),
 19 |       });
 20 |     }
 21 |   }
 22 | 
 23 |   // helper to provide event handlers for all links in a container
 24 |   function handleLinkClickEvents(deck, container) {
 25 |     Array.from(container.querySelectorAll("a")).forEach((el) => {
 26 |       const url = el.getAttribute("href");
 27 |       if (/^(http|www)/gi.test(url)) {
 28 |         el.addEventListener(
 29 |           "click",
 30 |           (ev) => {
 31 |             const fullscreen = !!window.document.fullscreen;
 32 |             const dataPreviewLink = el.getAttribute("data-preview-link");
 33 | 
 34 |             // if there is a local specifcation then use that
 35 |             if (dataPreviewLink) {
 36 |               if (
 37 |                 dataPreviewLink === "true" ||
 38 |                 (dataPreviewLink === "auto" && fullscreen)
 39 |               ) {
 40 |                 ev.preventDefault();
 41 |                 deck.showPreview(url);
 42 |                 return false;
 43 |               }
 44 |             } else {
 45 |               const previewLinks = !!deck.getConfig().previewLinks;
 46 |               const previewLinksAuto =
 47 |                 deck.getConfig().previewLinksAuto === true;
 48 |               if (previewLinks == true || (previewLinksAuto && fullscreen)) {
 49 |                 ev.preventDefault();
 50 |                 deck.showPreview(url);
 51 |                 return false;
 52 |               }
 53 |             }
 54 | 
 55 |             // if the deck is in an iframe we want to open it externally
 56 |             const iframe = window.location !== window.parent.location;
 57 |             if (iframe) {
 58 |               ev.preventDefault();
 59 |               ev.stopImmediatePropagation();
 60 |               window.open(url, "_blank");
 61 |               return false;
 62 |             }
 63 | 
 64 |             // if the user has set data-preview-link to "auto" we need to handle the event
 65 |             // (because reveal will interpret "auto" as true)
 66 |             if (dataPreviewLink === "auto") {
 67 |               ev.preventDefault();
 68 |               ev.stopImmediatePropagation();
 69 |               const target =
 70 |                 el.getAttribute("target") ||
 71 |                 (ev.ctrlKey || ev.metaKey ? "_blank" : "");
 72 |               if (target) {
 73 |                 window.open(url, target);
 74 |               } else {
 75 |                 window.location.href = url;
 76 |               }
 77 |               return false;
 78 |             }
 79 |           },
 80 |           false
 81 |         );
 82 |       }
 83 |     });
 84 |   }
 85 | 
 86 |   // implement previewLinksAuto
 87 |   function previewLinksAuto(deck) {
 88 |     handleLinkClickEvents(deck, deck.getRevealElement());
 89 |   }
 90 | 
 91 |   // apply styles
 92 |   function applyGlobalStyles(deck) {
 93 |     if (deck.getConfig()["smaller"] === true) {
 94 |       const revealParent = deck.getRevealElement();
 95 |       revealParent.classList.add("smaller");
 96 |     }
 97 |   }
 98 | 
 99 |   // add logo image
100 |   function addLogoImage(deck) {
101 |     const revealParent = deck.getRevealElement();
102 |     const logoImg = document.querySelector(".slide-logo");
103 |     if (logoImg) {
104 |       revealParent.appendChild(logoImg);
105 |       revealParent.classList.add("has-logo");
106 |     }
107 |   }
108 | 
109 |   // add footer text
110 |   function addFooter(deck) {
111 |     const revealParent = deck.getRevealElement();
112 |     const defaultFooterDiv = document.querySelector(".footer-default");
113 |     if (defaultFooterDiv) {
114 |       revealParent.appendChild(defaultFooterDiv);
115 |       handleLinkClickEvents(deck, defaultFooterDiv);
116 |       if (!isPrintView()) {
117 |         deck.on("slidechanged", function (ev) {
118 |           const prevSlideFooter = document.querySelector(
119 |             ".reveal > .footer:not(.footer-default)"
120 |           );
121 |           if (prevSlideFooter) {
122 |             prevSlideFooter.remove();
123 |           }
124 |           const currentSlideFooter = ev.currentSlide.querySelector(".footer");
125 |           if (currentSlideFooter) {
126 |             defaultFooterDiv.style.display = "none";
127 |             const slideFooter = currentSlideFooter.cloneNode(true);
128 |             handleLinkClickEvents(deck, slideFooter);
129 |             deck.getRevealElement().appendChild(slideFooter);
130 |           } else {
131 |             defaultFooterDiv.style.display = "block";
132 |           }
133 |         });
134 |       }
135 |     }
136 |   }
137 | 
138 |   // add chalkboard buttons
139 |   function addChalkboardButtons(deck) {
140 |     const chalkboard = deck.getPlugin("RevealChalkboard");
141 |     if (chalkboard && !isPrintView()) {
142 |       const revealParent = deck.getRevealElement();
143 |       const chalkboardDiv = document.createElement("div");
144 |       chalkboardDiv.classList.add("slide-chalkboard-buttons");
145 |       if (document.querySelector(".slide-menu-button")) {
146 |         chalkboardDiv.classList.add("slide-menu-offset");
147 |       }
148 |       // add buttons
149 |       const buttons = [
150 |         {
151 |           icon: "easel2",
152 |           title: "Toggle Chalkboard (b)",
153 |           onclick: chalkboard.toggleChalkboard,
154 |         },
155 |         {
156 |           icon: "brush",
157 |           title: "Toggle Notes Canvas (c)",
158 |           onclick: chalkboard.toggleNotesCanvas,
159 |         },
160 |       ];
161 |       buttons.forEach(function (button) {
162 |         const span = document.createElement("span");
163 |         span.title = button.title;
164 |         const icon = document.createElement("i");
165 |         icon.classList.add("fas");
166 |         icon.classList.add("fa-" + button.icon);
167 |         span.appendChild(icon);
168 |         span.onclick = function (event) {
169 |           event.preventDefault();
170 |           button.onclick();
171 |         };
172 |         chalkboardDiv.appendChild(span);
173 |       });
174 |       revealParent.appendChild(chalkboardDiv);
175 |       const config = deck.getConfig();
176 |       if (!config.chalkboard.buttons) {
177 |         chalkboardDiv.classList.add("hidden");
178 |       }
179 | 
180 |       // show and hide chalkboard buttons on slidechange
181 |       deck.on("slidechanged", function (ev) {
182 |         const config = deck.getConfig();
183 |         let buttons = !!config.chalkboard.buttons;
184 |         const slideButtons = ev.currentSlide.getAttribute(
185 |           "data-chalkboard-buttons"
186 |         );
187 |         if (slideButtons) {
188 |           if (slideButtons === "true" || slideButtons === "1") {
189 |             buttons = true;
190 |           } else if (slideButtons === "false" || slideButtons === "0") {
191 |             buttons = false;
192 |           }
193 |         }
194 |         if (buttons) {
195 |           chalkboardDiv.classList.remove("hidden");
196 |         } else {
197 |           chalkboardDiv.classList.add("hidden");
198 |         }
199 |       });
200 |     }
201 |   }
202 | 
203 |   function handleTabbyClicks() {
204 |     const tabs = document.querySelectorAll(".panel-tabset-tabby > li > a");
205 |     for (let i = 0; i < tabs.length; i++) {
206 |       const tab = tabs[i];
207 |       tab.onclick = function (ev) {
208 |         ev.preventDefault();
209 |         ev.stopPropagation();
210 |         return false;
211 |       };
212 |     }
213 |   }
214 | 
215 |   function fixupForPrint(deck) {
216 |     if (isPrintView()) {
217 |       const slides = deck.getSlides();
218 |       slides.forEach(function (slide) {
219 |         slide.removeAttribute("data-auto-animate");
220 |       });
221 |       window.document.querySelectorAll(".hljs").forEach(function (el) {
222 |         el.classList.remove("hljs");
223 |       });
224 |       window.document.querySelectorAll(".hljs-ln-code").forEach(function (el) {
225 |         el.classList.remove("hljs-ln-code");
226 |       });
227 |     }
228 |   }
229 | 
230 |   return {
231 |     id: "quarto-support",
232 |     init: function (deck) {
233 |       controlsAuto(deck);
234 |       previewLinksAuto(deck);
235 |       fixupForPrint(deck);
236 |       applyGlobalStyles(deck);
237 |       addLogoImage(deck);
238 |       addFooter(deck);
239 |       addChalkboardButtons(deck);
240 |       handleTabbyClicks();
241 |     },
242 |   };
243 | };
244 | 


--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/reveal-menu/menu.css:
--------------------------------------------------------------------------------
  1 | .slide-menu-wrapper {
  2 |   font-family: 'Source Sans Pro', Helvetica, sans-serif;
  3 | }
  4 | 
  5 | .slide-menu-wrapper .slide-menu {
  6 |   background-color: #333;
  7 |   z-index: 200;
  8 |   position: fixed;
  9 |   top: 0;
 10 |   width: 300px;
 11 |   height: 100%;
 12 |   /*overflow-y: scroll;*/
 13 |   transition: transform 0.3s;
 14 |   font-size: 16px;
 15 |   font-weight: normal;
 16 | }
 17 | 
 18 | .slide-menu-wrapper .slide-menu.slide-menu--wide {
 19 |   width: 500px;
 20 | }
 21 | 
 22 | .slide-menu-wrapper .slide-menu.slide-menu--third {
 23 |   width: 33%;
 24 | }
 25 | 
 26 | .slide-menu-wrapper .slide-menu.slide-menu--half {
 27 |   width: 50%;
 28 | }
 29 | 
 30 | .slide-menu-wrapper .slide-menu.slide-menu--full {
 31 |   width: 95%;
 32 | }
 33 | 
 34 | /*
 35 |  * Slides menu
 36 |  */
 37 | 
 38 | .slide-menu-wrapper .slide-menu-items {
 39 |   margin: 0;
 40 |   padding: 0;
 41 |   width: 100%;
 42 |   border-bottom: solid 1px #555;
 43 | }
 44 | 
 45 | .slide-menu-wrapper .slide-menu-item,
 46 | .slide-menu-wrapper .slide-menu-item-vertical {
 47 |   display: block;
 48 |   text-align: left;
 49 |   padding: 10px 18px;
 50 |   color: #aaa;
 51 |   cursor: pointer;
 52 | }
 53 | 
 54 | .slide-menu-wrapper .slide-menu-item-vertical {
 55 |   padding-left: 30px;
 56 | }
 57 | 
 58 | .slide-menu-wrapper .slide-menu--wide .slide-menu-item-vertical,
 59 | .slide-menu-wrapper .slide-menu--third .slide-menu-item-vertical,
 60 | .slide-menu-wrapper .slide-menu--half .slide-menu-item-vertical,
 61 | .slide-menu-wrapper .slide-menu--full .slide-menu-item-vertical,
 62 | .slide-menu-wrapper .slide-menu--custom .slide-menu-item-vertical {
 63 |   padding-left: 50px;
 64 | }
 65 | 
 66 | .slide-menu-wrapper .slide-menu-item {
 67 |   border-top: solid 1px #555;
 68 | }
 69 | 
 70 | .slide-menu-wrapper .active-menu-panel li.selected {
 71 |   background-color: #222;
 72 |   color: white;
 73 | }
 74 | 
 75 | .slide-menu-wrapper .active-menu-panel li.active {
 76 |   color: #eee;
 77 | }
 78 | 
 79 | .slide-menu-wrapper .slide-menu-item.no-title .slide-menu-item-title,
 80 | .slide-menu-wrapper .slide-menu-item-vertical.no-title .slide-menu-item-title {
 81 |   font-style: italic;
 82 | }
 83 | 
 84 | .slide-menu-wrapper .slide-menu-item-number {
 85 |   color: #999;
 86 |   padding-right: 6px;
 87 | }
 88 | 
 89 | .slide-menu-wrapper .slide-menu-item i.far,
 90 | .slide-menu-wrapper .slide-menu-item i.fas,
 91 | .slide-menu-wrapper .slide-menu-item-vertical i.far,
 92 | .slide-menu-wrapper .slide-menu-item-vertical i.fas,
 93 | .slide-menu-wrapper .slide-menu-item svg.svg-inline--fa,
 94 | .slide-menu-wrapper .slide-menu-item-vertical svg.svg-inline--fa {
 95 |   padding-right: 12px;
 96 |   display: none;
 97 | }
 98 | 
 99 | .slide-menu-wrapper .slide-menu-item.past i.fas.past,
100 | .slide-menu-wrapper .slide-menu-item-vertical.past i.fas.past,
101 | .slide-menu-wrapper .slide-menu-item.active i.fas.active,
102 | .slide-menu-wrapper .slide-menu-item-vertical.active i.fas.active,
103 | .slide-menu-wrapper .slide-menu-item.future i.far.future,
104 | .slide-menu-wrapper .slide-menu-item-vertical.future i.far.future,
105 | .slide-menu-wrapper .slide-menu-item.past svg.svg-inline--fa.past,
106 | .slide-menu-wrapper .slide-menu-item-vertical.past svg.svg-inline--fa.past,
107 | .slide-menu-wrapper .slide-menu-item.active svg.svg-inline--fa.active,
108 | .slide-menu-wrapper .slide-menu-item-vertical.active svg.svg-inline--fa.active,
109 | .slide-menu-wrapper .slide-menu-item.future svg.svg-inline--fa.future,
110 | .slide-menu-wrapper .slide-menu-item-vertical.future svg.svg-inline--fa.future {
111 |   display: inline-block;
112 | }
113 | 
114 | .slide-menu-wrapper .slide-menu-item.past i.fas.past,
115 | .slide-menu-wrapper .slide-menu-item-vertical.past i.fas.past,
116 | .slide-menu-wrapper .slide-menu-item.future i.far.future,
117 | .slide-menu-wrapper .slide-menu-item-vertical.future i.far.future,
118 | .slide-menu-wrapper .slide-menu-item.past svg.svg-inline--fa.past,
119 | .slide-menu-wrapper .slide-menu-item-vertical.past svg.svg-inline--fa.past,
120 | .slide-menu-wrapper .slide-menu-item.future svg.svg-inline--fa.future,
121 | .slide-menu-wrapper .slide-menu-item-vertical.future svg.svg-inline--fa.future {
122 |   opacity: 0.4;
123 | }
124 | 
125 | .slide-menu-wrapper .slide-menu-item.active i.fas.active,
126 | .slide-menu-wrapper .slide-menu-item-vertical.active i.fas.active,
127 | .slide-menu-wrapper .slide-menu-item.active svg.svg-inline--fa.active,
128 | .slide-menu-wrapper .slide-menu-item-vertical.active svg.svg-inline--fa.active {
129 |   opacity: 0.8;
130 | }
131 | 
132 | .slide-menu-wrapper .slide-menu--left {
133 |   left: 0;
134 |   -webkit-transform: translateX(-100%);
135 |   -ms-transform: translateX(-100%);
136 |   transform: translateX(-100%);
137 | }
138 | 
139 | .slide-menu-wrapper .slide-menu--left.active {
140 |   -webkit-transform: translateX(0);
141 |   -ms-transform: translateX(0);
142 |   transform: translateX(0);
143 | }
144 | 
145 | .slide-menu-wrapper .slide-menu--right {
146 |   right: 0;
147 |   -webkit-transform: translateX(100%);
148 |   -ms-transform: translateX(100%);
149 |   transform: translateX(100%);
150 | }
151 | 
152 | .slide-menu-wrapper .slide-menu--right.active {
153 |   -webkit-transform: translateX(0);
154 |   -ms-transform: translateX(0);
155 |   transform: translateX(0);
156 | }
157 | 
158 | .slide-menu-wrapper {
159 |   transition: transform 0.3s;
160 | }
161 | 
162 | /*
163 |  * Toolbar
164 |  */
165 | .slide-menu-wrapper .slide-menu-toolbar {
166 |   height: 60px;
167 |   width: 100%;
168 |   font-size: 12px;
169 |   display: table;
170 |   table-layout: fixed; /* ensures equal width */
171 |   margin: 0;
172 |   padding: 0;
173 |   border-bottom: solid 2px #666;
174 | }
175 | 
176 | .slide-menu-wrapper .slide-menu-toolbar > li {
177 |   display: table-cell;
178 |   line-height: 150%;
179 |   text-align: center;
180 |   vertical-align: middle;
181 |   cursor: pointer;
182 |   color: #aaa;
183 |   border-radius: 3px;
184 | }
185 | 
186 | .slide-menu-wrapper .slide-menu-toolbar > li.toolbar-panel-button i,
187 | .slide-menu-wrapper
188 |   .slide-menu-toolbar
189 |   > li.toolbar-panel-button
190 |   svg.svg-inline--fa {
191 |   font-size: 1.7em;
192 | }
193 | 
194 | .slide-menu-wrapper .slide-menu-toolbar > li.active-toolbar-button {
195 |   color: white;
196 |   text-shadow: 0 1px black;
197 |   text-decoration: underline;
198 | }
199 | 
200 | .slide-menu-toolbar > li.toolbar-panel-button:hover {
201 |   color: white;
202 | }
203 | 
204 | .slide-menu-toolbar
205 |   > li.toolbar-panel-button:hover
206 |   span.slide-menu-toolbar-label,
207 | .slide-menu-wrapper
208 |   .slide-menu-toolbar
209 |   > li.active-toolbar-button
210 |   span.slide-menu-toolbar-label {
211 |   visibility: visible;
212 | }
213 | 
214 | /*
215 |  * Panels
216 |  */
217 | .slide-menu-wrapper .slide-menu-panel {
218 |   position: absolute;
219 |   width: 100%;
220 |   visibility: hidden;
221 |   height: calc(100% - 60px);
222 |   overflow-x: hidden;
223 |   overflow-y: auto;
224 |   color: #aaa;
225 | }
226 | 
227 | .slide-menu-wrapper .slide-menu-panel.active-menu-panel {
228 |   visibility: visible;
229 | }
230 | 
231 | .slide-menu-wrapper .slide-menu-panel h1,
232 | .slide-menu-wrapper .slide-menu-panel h2,
233 | .slide-menu-wrapper .slide-menu-panel h3,
234 | .slide-menu-wrapper .slide-menu-panel h4,
235 | .slide-menu-wrapper .slide-menu-panel h5,
236 | .slide-menu-wrapper .slide-menu-panel h6 {
237 |   margin: 20px 0 10px 0;
238 |   color: #fff;
239 |   line-height: 1.2;
240 |   letter-spacing: normal;
241 |   text-shadow: none;
242 | }
243 | 
244 | .slide-menu-wrapper .slide-menu-panel h1 {
245 |   font-size: 1.6em;
246 | }
247 | .slide-menu-wrapper .slide-menu-panel h2 {
248 |   font-size: 1.4em;
249 | }
250 | .slide-menu-wrapper .slide-menu-panel h3 {
251 |   font-size: 1.3em;
252 | }
253 | .slide-menu-wrapper .slide-menu-panel h4 {
254 |   font-size: 1.1em;
255 | }
256 | .slide-menu-wrapper .slide-menu-panel h5 {
257 |   font-size: 1em;
258 | }
259 | .slide-menu-wrapper .slide-menu-panel h6 {
260 |   font-size: 0.9em;
261 | }
262 | 
263 | .slide-menu-wrapper .slide-menu-panel p {
264 |   margin: 10px 0 5px 0;
265 | }
266 | 
267 | .slide-menu-wrapper .slide-menu-panel a {
268 |   color: #ccc;
269 |   text-decoration: underline;
270 | }
271 | 
272 | .slide-menu-wrapper .slide-menu-panel a:hover {
273 |   color: white;
274 | }
275 | 
276 | .slide-menu-wrapper .slide-menu-item a {
277 |   text-decoration: none;
278 | }
279 | 
280 | .slide-menu-wrapper .slide-menu-custom-panel {
281 |   width: calc(100% - 20px);
282 |   padding-left: 10px;
283 |   padding-right: 10px;
284 | }
285 | 
286 | .slide-menu-wrapper .slide-menu-custom-panel .slide-menu-items {
287 |   width: calc(100% + 20px);
288 |   margin-left: -10px;
289 |   margin-right: 10px;
290 | }
291 | 
292 | /*
293 |  * Theme and Transitions buttons
294 |  */
295 | 
296 | .slide-menu-wrapper div[data-panel='Themes'] li,
297 | .slide-menu-wrapper div[data-panel='Transitions'] li {
298 |   display: block;
299 |   text-align: left;
300 |   cursor: pointer;
301 |   color: #848484;
302 | }
303 | 
304 | /*
305 |  * Menu controls
306 |  */
307 | .reveal .slide-menu-button {
308 |   position: fixed;
309 |   left: 30px;
310 |   bottom: 30px;
311 |   z-index: 30;
312 |   font-size: 24px;
313 | }
314 | 
315 | /*
316 |  * Menu overlay
317 |  */
318 | 
319 | .slide-menu-wrapper .slide-menu-overlay {
320 |   position: fixed;
321 |   z-index: 199;
322 |   top: 0;
323 |   left: 0;
324 |   overflow: hidden;
325 |   width: 0;
326 |   height: 0;
327 |   background-color: #000;
328 |   opacity: 0;
329 |   transition: opacity 0.3s, width 0s 0.3s, height 0s 0.3s;
330 | }
331 | 
332 | .slide-menu-wrapper .slide-menu-overlay.active {
333 |   width: 100%;
334 |   height: 100%;
335 |   opacity: 0.7;
336 |   transition: opacity 0.3s;
337 | }
338 | 
339 | /*
340 |  * Hide menu for pdf printing
341 |  */
342 | body.print-pdf .slide-menu-wrapper .slide-menu,
343 | body.print-pdf .reveal .slide-menu-button,
344 | body.print-pdf .slide-menu-wrapper .slide-menu-overlay {
345 |   display: none;
346 | }
347 | 


--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/reveal-menu/plugin.yml:
--------------------------------------------------------------------------------
 1 | name: RevealMenu
 2 | script: [menu.js, quarto-menu.js]
 3 | stylesheet: [menu.css, quarto-menu.css]
 4 | config:
 5 |   menu:
 6 |     side: "left"
 7 |     useTextContentForMissingTitles: true
 8 |     markers: false
 9 |     loadIcons: false
10 | 


--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/reveal-menu/quarto-menu.css:
--------------------------------------------------------------------------------
 1 | .slide-menu-wrapper .slide-tool-item {
 2 |   display: block;
 3 |   text-align: left;
 4 |   padding: 10px 18px;
 5 |   color: #aaa;
 6 |   cursor: pointer;
 7 |   border-top: solid 1px #555;
 8 | }
 9 | 
10 | .slide-menu-wrapper .slide-tool-item a {
11 |   text-decoration: none;
12 | }
13 | 
14 | .slide-menu-wrapper .slide-tool-item kbd {
15 |   font-family: monospace;
16 |   margin-right: 10px;
17 |   padding: 3px 8px;
18 |   color: inherit;
19 |   border: 1px solid;
20 |   border-radius: 5px;
21 |   border-color: #555;
22 | }
23 | 
24 | .slide-menu-wrapper .slide-menu-toolbar > li.active-toolbar-button {
25 |   text-decoration: none;
26 | }
27 | 
28 | .reveal .slide-menu-button {
29 |   left: 8px;
30 |   bottom: 8px;
31 | }
32 | 
33 | .reveal .slide-menu-button .fas::before,
34 | .reveal .slide-chalkboard-buttons .fas::before,
35 | .slide-menu-wrapper .slide-menu-toolbar .fas::before {
36 |   display: inline-block;
37 |   height: 2.2rem;
38 |   width: 2.2rem;
39 |   content: "";
40 |   vertical-align: -0.125em;
41 |   background-repeat: no-repeat;
42 |   background-size: 2.2rem 2.2rem;
43 | }
44 | 
45 | .reveal .slide-chalkboard-buttons .fas::before {
46 |   height: 1.45rem;
47 |   width: 1.45rem;
48 |   background-size: 1.45rem 1.45rem;
49 |   vertical-align: 0.1em;
50 | }
51 | 
52 | .slide-menu-wrapper .slide-menu-toolbar .fas::before {
53 |   height: 1.8rem;
54 |   width: 1.8rem;
55 |   background-size: 1.8rem 1.8rem;
56 | }
57 | 
58 | .slide-menu-wrapper .slide-menu-toolbar .fa-images::before {
59 |   background-image: url('data:image/svg+xml,');
60 | }
61 | 
62 | .slide-menu-wrapper .slide-menu-toolbar .fa-gear::before {
63 |   background-image: url('data:image/svg+xml,');
64 | }
65 | 
66 | .slide-menu-wrapper .slide-menu-toolbar .fa-times::before {
67 |   background-image: url('data:image/svg+xml,');
68 | }
69 | 


--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/reveal-menu/quarto-menu.js:
--------------------------------------------------------------------------------
 1 | window.revealMenuToolHandler = function (handler) {
 2 |   return function (event) {
 3 |     event.preventDefault();
 4 |     handler();
 5 |     Reveal.getPlugin("menu").closeMenu();
 6 |   };
 7 | };
 8 | 
 9 | window.RevealMenuToolHandlers = {
10 |   fullscreen: revealMenuToolHandler(function () {
11 |     const element = document.documentElement;
12 |     const requestMethod =
13 |       element.requestFullscreen ||
14 |       element.webkitRequestFullscreen ||
15 |       element.webkitRequestFullScreen ||
16 |       element.mozRequestFullScreen ||
17 |       element.msRequestFullscreen;
18 |     if (requestMethod) {
19 |       requestMethod.apply(element);
20 |     }
21 |   }),
22 |   speakerMode: revealMenuToolHandler(function () {
23 |     Reveal.getPlugin("notes").open();
24 |   }),
25 |   keyboardHelp: revealMenuToolHandler(function () {
26 |     Reveal.toggleHelp(true);
27 |   }),
28 |   overview: revealMenuToolHandler(function () {
29 |     Reveal.toggleOverview(true);
30 |   }),
31 |   toggleChalkboard: revealMenuToolHandler(function () {
32 |     RevealChalkboard.toggleChalkboard();
33 |   }),
34 |   toggleNotesCanvas: revealMenuToolHandler(function () {
35 |     RevealChalkboard.toggleNotesCanvas();
36 |   }),
37 |   downloadDrawings: revealMenuToolHandler(function () {
38 |     RevealChalkboard.download();
39 |   }),
40 | };
41 | 


--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/search/plugin.js:
--------------------------------------------------------------------------------
  1 | /*!
  2 |  * Handles finding a text string anywhere in the slides and showing the next occurrence to the user
  3 |  * by navigatating to that slide and highlighting it.
  4 |  *
  5 |  * @author Jon Snyder , February 2013
  6 |  */
  7 | 
  8 | const Plugin = () => {
  9 | 
 10 | 	// The reveal.js instance this plugin is attached to
 11 | 	let deck;
 12 | 
 13 | 	let searchElement;
 14 | 	let searchButton;
 15 | 	let searchInput;
 16 | 
 17 | 	let matchedSlides;
 18 | 	let currentMatchedIndex;
 19 | 	let searchboxDirty;
 20 | 	let hilitor;
 21 | 
 22 | 	function render() {
 23 | 
 24 | 		searchElement = document.createElement( 'div' );
 25 | 		searchElement.classList.add( 'searchbox' );
 26 | 		searchElement.style.position = 'absolute';
 27 | 		searchElement.style.top = '10px';
 28 | 		searchElement.style.right = '10px';
 29 | 		searchElement.style.zIndex = 10;
 30 | 
 31 | 		//embedded base64 search icon Designed by Sketchdock - http://www.sketchdock.com/:
 32 | 		searchElement.innerHTML = `
 33 | 		`;
 34 | 
 35 | 		searchInput = searchElement.querySelector( '.searchinput' );
 36 | 		searchInput.style.width = '240px';
 37 | 		searchInput.style.fontSize = '14px';
 38 | 		searchInput.style.padding = '4px 6px';
 39 | 		searchInput.style.color = '#000';
 40 | 		searchInput.style.background = '#fff';
 41 | 		searchInput.style.borderRadius = '2px';
 42 | 		searchInput.style.border = '0';
 43 | 		searchInput.style.outline = '0';
 44 | 		searchInput.style.boxShadow = '0 2px 18px rgba(0, 0, 0, 0.2)';
 45 | 		searchInput.style['-webkit-appearance']  = 'none';
 46 | 
 47 | 		deck.getRevealElement().appendChild( searchElement );
 48 | 
 49 | 		// searchButton.addEventListener( 'click', function(event) {
 50 | 		// 	doSearch();
 51 | 		// }, false );
 52 | 
 53 | 		searchInput.addEventListener( 'keyup', function( event ) {
 54 | 			switch (event.keyCode) {
 55 | 				case 13:
 56 | 					event.preventDefault();
 57 | 					doSearch();
 58 | 					searchboxDirty = false;
 59 | 					break;
 60 | 				default:
 61 | 					searchboxDirty = true;
 62 | 			}
 63 | 		}, false );
 64 | 
 65 | 		closeSearch();
 66 | 
 67 | 	}
 68 | 
 69 | 	function openSearch() {
 70 | 		if( !searchElement ) render();
 71 | 
 72 | 		searchElement.style.display = 'inline';
 73 | 		searchInput.focus();
 74 | 		searchInput.select();
 75 | 	}
 76 | 
 77 | 	function closeSearch() {
 78 | 		if( !searchElement ) render();
 79 | 
 80 | 		searchElement.style.display = 'none';
 81 | 		if(hilitor) hilitor.remove();
 82 | 	}
 83 | 
 84 | 	function toggleSearch() {
 85 | 		if( !searchElement ) render();
 86 | 
 87 | 		if (searchElement.style.display !== 'inline') {
 88 | 			openSearch();
 89 | 		}
 90 | 		else {
 91 | 			closeSearch();
 92 | 		}
 93 | 	}
 94 | 
 95 | 	function doSearch() {
 96 | 		//if there's been a change in the search term, perform a new search:
 97 | 		if (searchboxDirty) {
 98 | 			var searchstring = searchInput.value;
 99 | 
100 | 			if (searchstring === '') {
101 | 				if(hilitor) hilitor.remove();
102 | 				matchedSlides = null;
103 | 			}
104 | 			else {
105 | 				//find the keyword amongst the slides
106 | 				hilitor = new Hilitor("slidecontent");
107 | 				matchedSlides = hilitor.apply(searchstring);
108 | 				currentMatchedIndex = 0;
109 | 			}
110 | 		}
111 | 
112 | 		if (matchedSlides) {
113 | 			//navigate to the next slide that has the keyword, wrapping to the first if necessary
114 | 			if (matchedSlides.length && (matchedSlides.length <= currentMatchedIndex)) {
115 | 				currentMatchedIndex = 0;
116 | 			}
117 | 			if (matchedSlides.length > currentMatchedIndex) {
118 | 				deck.slide(matchedSlides[currentMatchedIndex].h, matchedSlides[currentMatchedIndex].v);
119 | 				currentMatchedIndex++;
120 | 			}
121 | 		}
122 | 	}
123 | 
124 | 	// Original JavaScript code by Chirp Internet: www.chirp.com.au
125 | 	// Please acknowledge use of this code by including this header.
126 | 	// 2/2013 jon: modified regex to display any match, not restricted to word boundaries.
127 | 	function Hilitor(id, tag) {
128 | 
129 | 		var targetNode = document.getElementById(id) || document.body;
130 | 		var hiliteTag = tag || "EM";
131 | 		var skipTags = new RegExp("^(?:" + hiliteTag + "|SCRIPT|FORM)$");
132 | 		var colors = ["#ff6", "#a0ffff", "#9f9", "#f99", "#f6f"];
133 | 		var wordColor = [];
134 | 		var colorIdx = 0;
135 | 		var matchRegex = "";
136 | 		var matchingSlides = [];
137 | 
138 | 		this.setRegex = function(input)
139 | 		{
140 | 			input = input.replace(/^[^\w]+|[^\w]+$/g, "").replace(/[^\w'-]+/g, "|");
141 | 			matchRegex = new RegExp("(" + input + ")","i");
142 | 		}
143 | 
144 | 		this.getRegex = function()
145 | 		{
146 | 			return matchRegex.toString().replace(/^\/\\b\(|\)\\b\/i$/g, "").replace(/\|/g, " ");
147 | 		}
148 | 
149 | 		// recursively apply word highlighting
150 | 		this.hiliteWords = function(node)
151 | 		{
152 | 			if(node == undefined || !node) return;
153 | 			if(!matchRegex) return;
154 | 			if(skipTags.test(node.nodeName)) return;
155 | 
156 | 			if(node.hasChildNodes()) {
157 | 				for(var i=0; i < node.childNodes.length; i++)
158 | 					this.hiliteWords(node.childNodes[i]);
159 | 			}
160 | 			if(node.nodeType == 3) { // NODE_TEXT
161 | 				var nv, regs;
162 | 				if((nv = node.nodeValue) && (regs = matchRegex.exec(nv))) {
163 | 					//find the slide's section element and save it in our list of matching slides
164 | 					var secnode = node;
165 | 					while (secnode != null && secnode.nodeName != 'SECTION') {
166 | 						secnode = secnode.parentNode;
167 | 					}
168 | 
169 | 					var slideIndex = deck.getIndices(secnode);
170 | 					var slidelen = matchingSlides.length;
171 | 					var alreadyAdded = false;
172 | 					for (var i=0; i < slidelen; i++) {
173 | 						if ( (matchingSlides[i].h === slideIndex.h) && (matchingSlides[i].v === slideIndex.v) ) {
174 | 							alreadyAdded = true;
175 | 						}
176 | 					}
177 | 					if (! alreadyAdded) {
178 | 						matchingSlides.push(slideIndex);
179 | 					}
180 | 
181 | 					if(!wordColor[regs[0].toLowerCase()]) {
182 | 						wordColor[regs[0].toLowerCase()] = colors[colorIdx++ % colors.length];
183 | 					}
184 | 
185 | 					var match = document.createElement(hiliteTag);
186 | 					match.appendChild(document.createTextNode(regs[0]));
187 | 					match.style.backgroundColor = wordColor[regs[0].toLowerCase()];
188 | 					match.style.fontStyle = "inherit";
189 | 					match.style.color = "#000";
190 | 
191 | 					var after = node.splitText(regs.index);
192 | 					after.nodeValue = after.nodeValue.substring(regs[0].length);
193 | 					node.parentNode.insertBefore(match, after);
194 | 				}
195 | 			}
196 | 		};
197 | 
198 | 		// remove highlighting
199 | 		this.remove = function()
200 | 		{
201 | 			var arr = document.getElementsByTagName(hiliteTag);
202 | 			var el;
203 | 			while(arr.length && (el = arr[0])) {
204 | 				el.parentNode.replaceChild(el.firstChild, el);
205 | 			}
206 | 		};
207 | 
208 | 		// start highlighting at target node
209 | 		this.apply = function(input)
210 | 		{
211 | 			if(input == undefined || !input) return;
212 | 			this.remove();
213 | 			this.setRegex(input);
214 | 			this.hiliteWords(targetNode);
215 | 			return matchingSlides;
216 | 		};
217 | 
218 | 	}
219 | 
220 | 	return {
221 | 
222 | 		id: 'search',
223 | 
224 | 		init: reveal => {
225 | 
226 | 			deck = reveal;
227 | 			deck.registerKeyboardShortcut( 'CTRL + Shift + F', 'Search' );
228 | 
229 | 			document.addEventListener( 'keydown', function( event ) {
230 | 				if( event.key == "F" && (event.ctrlKey || event.metaKey) ) { //Control+Shift+f
231 | 					event.preventDefault();
232 | 					toggleSearch();
233 | 				}
234 | 			}, false );
235 | 
236 | 		},
237 | 
238 | 		open: openSearch
239 | 
240 | 	}
241 | };
242 | 
243 | export default Plugin;


--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/zoom/plugin.js:
--------------------------------------------------------------------------------
  1 | /*!
  2 |  * reveal.js Zoom plugin
  3 |  */
  4 | const Plugin = {
  5 | 
  6 | 	id: 'zoom',
  7 | 
  8 | 	init: function( reveal ) {
  9 | 
 10 | 		reveal.getRevealElement().addEventListener( 'mousedown', function( event ) {
 11 | 			var defaultModifier = /Linux/.test( window.navigator.platform ) ? 'ctrl' : 'alt';
 12 | 
 13 | 			var modifier = ( reveal.getConfig().zoomKey ? reveal.getConfig().zoomKey : defaultModifier ) + 'Key';
 14 | 			var zoomLevel = ( reveal.getConfig().zoomLevel ? reveal.getConfig().zoomLevel : 2 );
 15 | 
 16 | 			if( event[ modifier ] && !reveal.isOverview() ) {
 17 | 				event.preventDefault();
 18 | 
 19 | 				zoom.to({
 20 | 					x: event.clientX,
 21 | 					y: event.clientY,
 22 | 					scale: zoomLevel,
 23 | 					pan: false
 24 | 				});
 25 | 			}
 26 | 		} );
 27 | 
 28 | 	}
 29 | 
 30 | };
 31 | 
 32 | export default () => Plugin;
 33 | 
 34 | /*!
 35 |  * zoom.js 0.3 (modified for use with reveal.js)
 36 |  * http://lab.hakim.se/zoom-js
 37 |  * MIT licensed
 38 |  *
 39 |  * Copyright (C) 2011-2014 Hakim El Hattab, http://hakim.se
 40 |  */
 41 | var zoom = (function(){
 42 | 
 43 | 	// The current zoom level (scale)
 44 | 	var level = 1;
 45 | 
 46 | 	// The current mouse position, used for panning
 47 | 	var mouseX = 0,
 48 | 		mouseY = 0;
 49 | 
 50 | 	// Timeout before pan is activated
 51 | 	var panEngageTimeout = -1,
 52 | 		panUpdateInterval = -1;
 53 | 
 54 | 	// Check for transform support so that we can fallback otherwise
 55 | 	var supportsTransforms = 	'WebkitTransform' in document.body.style ||
 56 | 								'MozTransform' in document.body.style ||
 57 | 								'msTransform' in document.body.style ||
 58 | 								'OTransform' in document.body.style ||
 59 | 								'transform' in document.body.style;
 60 | 
 61 | 	if( supportsTransforms ) {
 62 | 		// The easing that will be applied when we zoom in/out
 63 | 		document.body.style.transition = 'transform 0.8s ease';
 64 | 		document.body.style.OTransition = '-o-transform 0.8s ease';
 65 | 		document.body.style.msTransition = '-ms-transform 0.8s ease';
 66 | 		document.body.style.MozTransition = '-moz-transform 0.8s ease';
 67 | 		document.body.style.WebkitTransition = '-webkit-transform 0.8s ease';
 68 | 	}
 69 | 
 70 | 	// Zoom out if the user hits escape
 71 | 	document.addEventListener( 'keyup', function( event ) {
 72 | 		if( level !== 1 && event.keyCode === 27 ) {
 73 | 			zoom.out();
 74 | 		}
 75 | 	} );
 76 | 
 77 | 	// Monitor mouse movement for panning
 78 | 	document.addEventListener( 'mousemove', function( event ) {
 79 | 		if( level !== 1 ) {
 80 | 			mouseX = event.clientX;
 81 | 			mouseY = event.clientY;
 82 | 		}
 83 | 	} );
 84 | 
 85 | 	/**
 86 | 	 * Applies the CSS required to zoom in, prefers the use of CSS3
 87 | 	 * transforms but falls back on zoom for IE.
 88 | 	 *
 89 | 	 * @param {Object} rect
 90 | 	 * @param {Number} scale
 91 | 	 */
 92 | 	function magnify( rect, scale ) {
 93 | 
 94 | 		var scrollOffset = getScrollOffset();
 95 | 
 96 | 		// Ensure a width/height is set
 97 | 		rect.width = rect.width || 1;
 98 | 		rect.height = rect.height || 1;
 99 | 
100 | 		// Center the rect within the zoomed viewport
101 | 		rect.x -= ( window.innerWidth - ( rect.width * scale ) ) / 2;
102 | 		rect.y -= ( window.innerHeight - ( rect.height * scale ) ) / 2;
103 | 
104 | 		if( supportsTransforms ) {
105 | 			// Reset
106 | 			if( scale === 1 ) {
107 | 				document.body.style.transform = '';
108 | 				document.body.style.OTransform = '';
109 | 				document.body.style.msTransform = '';
110 | 				document.body.style.MozTransform = '';
111 | 				document.body.style.WebkitTransform = '';
112 | 			}
113 | 			// Scale
114 | 			else {
115 | 				var origin = scrollOffset.x +'px '+ scrollOffset.y +'px',
116 | 					transform = 'translate('+ -rect.x +'px,'+ -rect.y +'px) scale('+ scale +')';
117 | 
118 | 				document.body.style.transformOrigin = origin;
119 | 				document.body.style.OTransformOrigin = origin;
120 | 				document.body.style.msTransformOrigin = origin;
121 | 				document.body.style.MozTransformOrigin = origin;
122 | 				document.body.style.WebkitTransformOrigin = origin;
123 | 
124 | 				document.body.style.transform = transform;
125 | 				document.body.style.OTransform = transform;
126 | 				document.body.style.msTransform = transform;
127 | 				document.body.style.MozTransform = transform;
128 | 				document.body.style.WebkitTransform = transform;
129 | 			}
130 | 		}
131 | 		else {
132 | 			// Reset
133 | 			if( scale === 1 ) {
134 | 				document.body.style.position = '';
135 | 				document.body.style.left = '';
136 | 				document.body.style.top = '';
137 | 				document.body.style.width = '';
138 | 				document.body.style.height = '';
139 | 				document.body.style.zoom = '';
140 | 			}
141 | 			// Scale
142 | 			else {
143 | 				document.body.style.position = 'relative';
144 | 				document.body.style.left = ( - ( scrollOffset.x + rect.x ) / scale ) + 'px';
145 | 				document.body.style.top = ( - ( scrollOffset.y + rect.y ) / scale ) + 'px';
146 | 				document.body.style.width = ( scale * 100 ) + '%';
147 | 				document.body.style.height = ( scale * 100 ) + '%';
148 | 				document.body.style.zoom = scale;
149 | 			}
150 | 		}
151 | 
152 | 		level = scale;
153 | 
154 | 		if( document.documentElement.classList ) {
155 | 			if( level !== 1 ) {
156 | 				document.documentElement.classList.add( 'zoomed' );
157 | 			}
158 | 			else {
159 | 				document.documentElement.classList.remove( 'zoomed' );
160 | 			}
161 | 		}
162 | 	}
163 | 
164 | 	/**
165 | 	 * Pan the document when the mosue cursor approaches the edges
166 | 	 * of the window.
167 | 	 */
168 | 	function pan() {
169 | 		var range = 0.12,
170 | 			rangeX = window.innerWidth * range,
171 | 			rangeY = window.innerHeight * range,
172 | 			scrollOffset = getScrollOffset();
173 | 
174 | 		// Up
175 | 		if( mouseY < rangeY ) {
176 | 			window.scroll( scrollOffset.x, scrollOffset.y - ( 1 - ( mouseY / rangeY ) ) * ( 14 / level ) );
177 | 		}
178 | 		// Down
179 | 		else if( mouseY > window.innerHeight - rangeY ) {
180 | 			window.scroll( scrollOffset.x, scrollOffset.y + ( 1 - ( window.innerHeight - mouseY ) / rangeY ) * ( 14 / level ) );
181 | 		}
182 | 
183 | 		// Left
184 | 		if( mouseX < rangeX ) {
185 | 			window.scroll( scrollOffset.x - ( 1 - ( mouseX / rangeX ) ) * ( 14 / level ), scrollOffset.y );
186 | 		}
187 | 		// Right
188 | 		else if( mouseX > window.innerWidth - rangeX ) {
189 | 			window.scroll( scrollOffset.x + ( 1 - ( window.innerWidth - mouseX ) / rangeX ) * ( 14 / level ), scrollOffset.y );
190 | 		}
191 | 	}
192 | 
193 | 	function getScrollOffset() {
194 | 		return {
195 | 			x: window.scrollX !== undefined ? window.scrollX : window.pageXOffset,
196 | 			y: window.scrollY !== undefined ? window.scrollY : window.pageYOffset
197 | 		}
198 | 	}
199 | 
200 | 	return {
201 | 		/**
202 | 		 * Zooms in on either a rectangle or HTML element.
203 | 		 *
204 | 		 * @param {Object} options
205 | 		 *   - element: HTML element to zoom in on
206 | 		 *   OR
207 | 		 *   - x/y: coordinates in non-transformed space to zoom in on
208 | 		 *   - width/height: the portion of the screen to zoom in on
209 | 		 *   - scale: can be used instead of width/height to explicitly set scale
210 | 		 */
211 | 		to: function( options ) {
212 | 
213 | 			// Due to an implementation limitation we can't zoom in
214 | 			// to another element without zooming out first
215 | 			if( level !== 1 ) {
216 | 				zoom.out();
217 | 			}
218 | 			else {
219 | 				options.x = options.x || 0;
220 | 				options.y = options.y || 0;
221 | 
222 | 				// If an element is set, that takes precedence
223 | 				if( !!options.element ) {
224 | 					// Space around the zoomed in element to leave on screen
225 | 					var padding = 20;
226 | 					var bounds = options.element.getBoundingClientRect();
227 | 
228 | 					options.x = bounds.left - padding;
229 | 					options.y = bounds.top - padding;
230 | 					options.width = bounds.width + ( padding * 2 );
231 | 					options.height = bounds.height + ( padding * 2 );
232 | 				}
233 | 
234 | 				// If width/height values are set, calculate scale from those values
235 | 				if( options.width !== undefined && options.height !== undefined ) {
236 | 					options.scale = Math.max( Math.min( window.innerWidth / options.width, window.innerHeight / options.height ), 1 );
237 | 				}
238 | 
239 | 				if( options.scale > 1 ) {
240 | 					options.x *= options.scale;
241 | 					options.y *= options.scale;
242 | 
243 | 					magnify( options, options.scale );
244 | 
245 | 					if( options.pan !== false ) {
246 | 
247 | 						// Wait with engaging panning as it may conflict with the
248 | 						// zoom transition
249 | 						panEngageTimeout = setTimeout( function() {
250 | 							panUpdateInterval = setInterval( pan, 1000 / 60 );
251 | 						}, 800 );
252 | 
253 | 					}
254 | 				}
255 | 			}
256 | 		},
257 | 
258 | 		/**
259 | 		 * Resets the document zoom state to its default.
260 | 		 */
261 | 		out: function() {
262 | 			clearTimeout( panEngageTimeout );
263 | 			clearInterval( panUpdateInterval );
264 | 
265 | 			magnify( { x: 0, y: 0 }, 1 );
266 | 
267 | 			level = 1;
268 | 		},
269 | 
270 | 		// Alias
271 | 		magnify: function( options ) { this.to( options ) },
272 | 		reset: function() { this.out() },
273 | 
274 | 		zoomLevel: function() {
275 | 			return level;
276 | 		}
277 | 	}
278 | 
279 | })();
280 | 


--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/zoom/zoom.esm.js:
--------------------------------------------------------------------------------
1 | /*!
2 |  * reveal.js Zoom plugin
3 |  */
4 | var e={id:"zoom",init:function(e){e.getRevealElement().addEventListener("mousedown",(function(o){var n=/Linux/.test(window.navigator.platform)?"ctrl":"alt",i=(e.getConfig().zoomKey?e.getConfig().zoomKey:n)+"Key",d=e.getConfig().zoomLevel?e.getConfig().zoomLevel:2;o[i]&&!e.isOverview()&&(o.preventDefault(),t.to({x:o.clientX,y:o.clientY,scale:d,pan:!1}))}))}},t=function(){var e=1,o=0,n=0,i=-1,d=-1,s="WebkitTransform"in document.body.style||"MozTransform"in document.body.style||"msTransform"in document.body.style||"OTransform"in document.body.style||"transform"in document.body.style;function r(t,o){var n=y();if(t.width=t.width||1,t.height=t.height||1,t.x-=(window.innerWidth-t.width*o)/2,t.y-=(window.innerHeight-t.height*o)/2,s)if(1===o)document.body.style.transform="",document.body.style.OTransform="",document.body.style.msTransform="",document.body.style.MozTransform="",document.body.style.WebkitTransform="";else{var i=n.x+"px "+n.y+"px",d="translate("+-t.x+"px,"+-t.y+"px) scale("+o+")";document.body.style.transformOrigin=i,document.body.style.OTransformOrigin=i,document.body.style.msTransformOrigin=i,document.body.style.MozTransformOrigin=i,document.body.style.WebkitTransformOrigin=i,document.body.style.transform=d,document.body.style.OTransform=d,document.body.style.msTransform=d,document.body.style.MozTransform=d,document.body.style.WebkitTransform=d}else 1===o?(document.body.style.position="",document.body.style.left="",document.body.style.top="",document.body.style.width="",document.body.style.height="",document.body.style.zoom=""):(document.body.style.position="relative",document.body.style.left=-(n.x+t.x)/o+"px",document.body.style.top=-(n.y+t.y)/o+"px",document.body.style.width=100*o+"%",document.body.style.height=100*o+"%",document.body.style.zoom=o);e=o,document.documentElement.classList&&(1!==e?document.documentElement.classList.add("zoomed"):document.documentElement.classList.remove("zoomed"))}function m(){var t=.12*window.innerWidth,i=.12*window.innerHeight,d=y();nwindow.innerHeight-i&&window.scroll(d.x,d.y+(1-(window.innerHeight-n)/i)*(14/e)),owindow.innerWidth-t&&window.scroll(d.x+(1-(window.innerWidth-o)/t)*(14/e),d.y)}function y(){return{x:void 0!==window.scrollX?window.scrollX:window.pageXOffset,y:void 0!==window.scrollY?window.scrollY:window.pageYOffset}}return s&&(document.body.style.transition="transform 0.8s ease",document.body.style.OTransition="-o-transform 0.8s ease",document.body.style.msTransition="-ms-transform 0.8s ease",document.body.style.MozTransition="-moz-transform 0.8s ease",document.body.style.WebkitTransition="-webkit-transform 0.8s ease"),document.addEventListener("keyup",(function(o){1!==e&&27===o.keyCode&&t.out()})),document.addEventListener("mousemove",(function(t){1!==e&&(o=t.clientX,n=t.clientY)})),{to:function(o){if(1!==e)t.out();else{if(o.x=o.x||0,o.y=o.y||0,o.element){var n=o.element.getBoundingClientRect();o.x=n.left-20,o.y=n.top-20,o.width=n.width+40,o.height=n.height+40}void 0!==o.width&&void 0!==o.height&&(o.scale=Math.max(Math.min(window.innerWidth/o.width,window.innerHeight/o.height),1)),o.scale>1&&(o.x*=o.scale,o.y*=o.scale,r(o,o.scale),!1!==o.pan&&(i=setTimeout((function(){d=setInterval(m,1e3/60)}),800)))}},out:function(){clearTimeout(i),clearInterval(d),r({x:0,y:0},1),e=1},magnify:function(e){this.to(e)},reset:function(){this.out()},zoomLevel:function(){return e}}}();export default function(){return e}
5 | 


--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/zoom/zoom.js:
--------------------------------------------------------------------------------
1 | !function(e,o){"object"==typeof exports&&"undefined"!=typeof module?module.exports=o():"function"==typeof define&&define.amd?define(o):(e="undefined"!=typeof globalThis?globalThis:e||self).RevealZoom=o()}(this,(function(){"use strict";
2 | /*!
3 | 	 * reveal.js Zoom plugin
4 | 	 */var e={id:"zoom",init:function(e){e.getRevealElement().addEventListener("mousedown",(function(t){var n=/Linux/.test(window.navigator.platform)?"ctrl":"alt",i=(e.getConfig().zoomKey?e.getConfig().zoomKey:n)+"Key",d=e.getConfig().zoomLevel?e.getConfig().zoomLevel:2;t[i]&&!e.isOverview()&&(t.preventDefault(),o.to({x:t.clientX,y:t.clientY,scale:d,pan:!1}))}))}},o=function(){var e=1,t=0,n=0,i=-1,d=-1,s="WebkitTransform"in document.body.style||"MozTransform"in document.body.style||"msTransform"in document.body.style||"OTransform"in document.body.style||"transform"in document.body.style;function r(o,t){var n=l();if(o.width=o.width||1,o.height=o.height||1,o.x-=(window.innerWidth-o.width*t)/2,o.y-=(window.innerHeight-o.height*t)/2,s)if(1===t)document.body.style.transform="",document.body.style.OTransform="",document.body.style.msTransform="",document.body.style.MozTransform="",document.body.style.WebkitTransform="";else{var i=n.x+"px "+n.y+"px",d="translate("+-o.x+"px,"+-o.y+"px) scale("+t+")";document.body.style.transformOrigin=i,document.body.style.OTransformOrigin=i,document.body.style.msTransformOrigin=i,document.body.style.MozTransformOrigin=i,document.body.style.WebkitTransformOrigin=i,document.body.style.transform=d,document.body.style.OTransform=d,document.body.style.msTransform=d,document.body.style.MozTransform=d,document.body.style.WebkitTransform=d}else 1===t?(document.body.style.position="",document.body.style.left="",document.body.style.top="",document.body.style.width="",document.body.style.height="",document.body.style.zoom=""):(document.body.style.position="relative",document.body.style.left=-(n.x+o.x)/t+"px",document.body.style.top=-(n.y+o.y)/t+"px",document.body.style.width=100*t+"%",document.body.style.height=100*t+"%",document.body.style.zoom=t);e=t,document.documentElement.classList&&(1!==e?document.documentElement.classList.add("zoomed"):document.documentElement.classList.remove("zoomed"))}function m(){var o=.12*window.innerWidth,i=.12*window.innerHeight,d=l();nwindow.innerHeight-i&&window.scroll(d.x,d.y+(1-(window.innerHeight-n)/i)*(14/e)),twindow.innerWidth-o&&window.scroll(d.x+(1-(window.innerWidth-t)/o)*(14/e),d.y)}function l(){return{x:void 0!==window.scrollX?window.scrollX:window.pageXOffset,y:void 0!==window.scrollY?window.scrollY:window.pageYOffset}}return s&&(document.body.style.transition="transform 0.8s ease",document.body.style.OTransition="-o-transform 0.8s ease",document.body.style.msTransition="-ms-transform 0.8s ease",document.body.style.MozTransition="-moz-transform 0.8s ease",document.body.style.WebkitTransition="-webkit-transform 0.8s ease"),document.addEventListener("keyup",(function(t){1!==e&&27===t.keyCode&&o.out()})),document.addEventListener("mousemove",(function(o){1!==e&&(t=o.clientX,n=o.clientY)})),{to:function(t){if(1!==e)o.out();else{if(t.x=t.x||0,t.y=t.y||0,t.element){var n=t.element.getBoundingClientRect();t.x=n.left-20,t.y=n.top-20,t.width=n.width+40,t.height=n.height+40}void 0!==t.width&&void 0!==t.height&&(t.scale=Math.max(Math.min(window.innerWidth/t.width,window.innerHeight/t.height),1)),t.scale>1&&(t.x*=t.scale,t.y*=t.scale,r(t,t.scale),!1!==t.pan&&(i=setTimeout((function(){d=setInterval(m,1e3/60)}),800)))}},out:function(){clearTimeout(i),clearInterval(d),r({x:0,y:0},1),e=1},magnify:function(e){this.to(e)},reset:function(){this.out()},zoomLevel:function(){return e}}}();return function(){return e}}));
5 | 


--------------------------------------------------------------------------------
/page-layout/README.md:
--------------------------------------------------------------------------------
1 | ## Page layout example
2 | 
3 | 


--------------------------------------------------------------------------------
/page-layout/requirements.txt:
--------------------------------------------------------------------------------
1 | jupyter
2 | 


--------------------------------------------------------------------------------
/page-layout/skeleton.bib:
--------------------------------------------------------------------------------
 1 | @Manual{R-base,
 2 |   title = {R: A Language and Environment for Statistical Computing},
 3 |   author = {{R Core Team}},
 4 |   organization = {R Foundation for Statistical Computing},
 5 |   address = {Vienna, Austria},
 6 |   year = {2021},
 7 |   url = {https://www.R-project.org/},
 8 | }
 9 | 
10 | @Manual{R-rmarkdown,
11 |   title = {rmarkdown: Dynamic Documents for R},
12 |   author = {JJ Allaire and Yihui Xie and Jonathan McPherson and Javier Luraschi and Kevin Ushey and Aron Atkins and Hadley Wickham and Joe Cheng and Winston Chang and Richard Iannone},
13 |   year = {2021},
14 |   note = {R package version 2.11},
15 |   url = {https://CRAN.R-project.org/package=rmarkdown},
16 | }
17 | 
18 | @Book{rmarkdown2018,
19 |   title = {R Markdown: The Definitive Guide},
20 |   author = {Yihui Xie and J.J. Allaire and Garrett Grolemund},
21 |   publisher = {Chapman and Hall/CRC},
22 |   address = {Boca Raton, Florida},
23 |   year = {2018},
24 |   note = {ISBN 9781138359338},
25 |   url = {https://bookdown.org/yihui/rmarkdown},
26 | }
27 | 
28 | @Book{rmarkdown2020,
29 |   title = {R Markdown Cookbook},
30 |   author = {Yihui Xie and Christophe Dervieux and Emily Riederer},
31 |   publisher = {Chapman and Hall/CRC},
32 |   address = {Boca Raton, Florida},
33 |   year = {2020},
34 |   note = {ISBN 9780367563837},
35 |   url = {https://bookdown.org/yihui/rmarkdown-cookbook},
36 | }
37 | 
38 | 
39 | @inbook{xie2018,
40 | 	title = {Tufte Handouts},
41 | 	author = {Xie, Yihui and Allaire, J. J. and Grolemund, Garrett},
42 | 	year = {2018},
43 | 	month = {07},
44 | 	date = {2018-07-27},
45 | 	publisher = {Chapman and Hall/CRC},
46 | 	booktitle = {R Markdown: The Definitive Guide},
47 | 	pages = {137--146},
48 | 	doi = {10.1201/9781138359444-6},
49 | 	url = {http://dx.doi.org/10.1201/9781138359444-6}
50 | }
51 | 


--------------------------------------------------------------------------------
/page-layout/tufte.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/page-layout/tufte.pdf


--------------------------------------------------------------------------------
/page-layout/tufte.qmd:
--------------------------------------------------------------------------------
  1 | ---
  2 | title: "A Quarto Page Layout Example"
  3 | subtitle: "Inspired by Tufte Handout, Using Quarto"
  4 | date: "`r Sys.Date()`"
  5 | format:
  6 |     pdf: default
  7 |     html: 
  8 |       self-contained: true
  9 |       grid: 
 10 |         margin-width: 350px
 11 | execute: 
 12 |   echo: fenced
 13 | reference-location: margin
 14 | citation-location: margin
 15 | bibliography: skeleton.bib
 16 | ---
 17 | 
 18 | # Introduction
 19 | 
 20 | This document demonstrates the use of a number of advanced page layout features to produce an attractive and usable document inspired by the Tufte handout style and the use of Tufte's styles in RMarkdown documents [@xie2018]. The Tufte handout style is a style that Edward Tufte uses in his books and handouts. Tufte's style is known for its extensive use of sidenotes, tight integration of graphics with text, and well-set typography. Quarto[^1] supports most of the layout techniques that are used in the Tufte handout style for both HTML and LaTeX/PDF output.
 21 | 
 22 | [^1]: To learn more, you can read more about [Quarto](https://www.quarto.org) or visit [Quarto's Github repository](https://www.github.com/quarto-dev/quarto-cli).
 23 | 
 24 | ``` yaml
 25 | ---
 26 | title: "An Example Using the Tufte Style"
 27 | author: "John Smith"
 28 | format:
 29 |   html:
 30 |     grid:
 31 |       margin-width: 350px         # <1>
 32 |   pdf: default
 33 | reference-location: margin        # <2>
 34 | citation-location: margin         # <2>
 35 | ---
 36 | ```
 37 | 
 38 | 1.  Increases the width of the margin to make more room for sidenotes and margin figures (HTML only).
 39 | 2.  Places footnotes and cited sources in the margin. Other layout options (for example placing a figure in the margin) will be set per element in examples below.
 40 | 
 41 | These layout features are designed with two important goals in mind:
 42 | 
 43 | 1.  To produce both PDF and HTML output with similar styles from the same Quarto document;
 44 | 2.  To provide simple syntax to write elements of the Tufte style such as side notes and margin figures. If you'd like a figure placed in the margin, just set the option `fig-column: margin` for your code chunk, and we will take care of the details for you[^2].
 45 | 
 46 | [^2]: You never need to think about `\begin{marginfigure}` or ``; the LaTeX and HTML code under the hood may be complicated, but you never need to learn or write such code.
 47 | 
 48 | If you have any feature requests or find bugs in these capabilities, please do not hesitate to file them to .
 49 | 
 50 | # Figures
 51 | 
 52 | ## Margin Figures
 53 | 
 54 | Images and graphics play an integral role in Tufte's work. To place figures in the margin you can use the **Quarto** chunk option `column: margin`. For example:
 55 | 
 56 | ```{r}
 57 | #| label: fig-margin
 58 | #| fig-cap: "MPG vs horsepower, colored by transmission."
 59 | #| column: margin
 60 | #| message: false
 61 | library(ggplot2)
 62 | mtcars2 <- mtcars
 63 | mtcars2$am <- factor(
 64 |   mtcars$am, labels = c('automatic', 'manual')
 65 | )
 66 | ggplot(mtcars2, aes(hp, mpg, color = am)) +
 67 |   geom_point() + geom_smooth() +
 68 |   theme(legend.position = 'bottom')
 69 | ```
 70 | 
 71 | Note the use of the `fig-cap` chunk option to provide a figure caption. You can adjust the proportions of figures using the `fig-width` and `fig-height` chunk options. These are specified in inches, and will be automatically scaled down to fit within the handout margin.
 72 | 
 73 | ## Arbitrary Margin Content
 74 | 
 75 | You can include anything in the margin by places the class `.column-margin` on the element. See an example on the right about the first fundamental theorem of calculus.
 76 | 
 77 | ::: column-margin
 78 | We know from *the first fundamental theorem of calculus* that for $x$ in $[a, b]$:
 79 | 
 80 | $$\frac{d}{dx}\left( \int_{a}^{x} f(u)\,du\right)=f(x).$$
 81 | :::
 82 | 
 83 | ## Full Width Figures
 84 | 
 85 | You can arrange for figures to span across the entire page by using the chunk option `fig-column: page-right`.
 86 | 
 87 | ```{r}
 88 | #| label: fig-fullwidth
 89 | #| fig-cap: "A full width figure."
 90 | #| fig-width: 11
 91 | #| fig-height: 3
 92 | #| fig-column: page-right
 93 | #| warning: false
 94 | ggplot(diamonds, aes(carat, price)) + geom_smooth() +
 95 |   facet_grid(~ cut)
 96 | ```
 97 | 
 98 | Other chunk options related to figures can still be used, such as `fig-width`, `fig-cap`, and so on. For full width figures, usually `fig-width` is large and `fig-height` is small. In the above example, the plot size is $11 \times 3$.
 99 | 
100 | ## Arbitrary Full Width Content
101 | 
102 | Any content can span to the full width of the page, simply place the element in a `div` and add the class `column-page-right`. For example, the following code will display its contents as full width.
103 | 
104 | ``` md
105 | ::: {.fullwidth}
106 | Any _full width_ content here.
107 | :::
108 | ```
109 | 
110 | Below is an example:
111 | 
112 | ::: column-page-right
113 | *R is free software and comes with ABSOLUTELY NO WARRANTY.* You are welcome to redistribute it under the terms of the GNU General Public License versions 2 or 3. For more information about these matters see .
114 | :::
115 | 
116 | ## Main Column Figures
117 | 
118 | Besides margin and full width figures, you can of course also include figures constrained to the main column. This is the default type of figures in the LaTeX/HTML output.
119 | 
120 | ```{r}
121 | #| label: fig-main
122 | #| fig-cap: "A figure in the main column."
123 | ggplot(diamonds, aes(cut, price)) + geom_boxplot()
124 | ```
125 | 
126 | ## Margin Captions
127 | 
128 | When you include a figure constrained to the main column, you can choose to place the figure's caption in the margin by using the `cap-location` chunk option. For example:
129 | 
130 | ```{r}
131 | #| label: fig-main-margin-cap
132 | #| fig-cap: "A figure with a longer caption. The figure appears in the main column, but the caption is placed in the margin. Captions can even contain elements like a citation such as @xie2018."
133 | #| cap-location: margin
134 | ggplot(diamonds, aes(cut, price)) + geom_boxplot()
135 | ```
136 | 
137 | # Sidenotes
138 | 
139 | One of the most prominent and distinctive features of this style is the extensive use of sidenotes. There is a wide margin to provide ample room for sidenotes and small figures. Any use of a footnote will automatically be converted to a sidenote.
140 | 
141 | [This is a span that has the class `column-margin` which places it in the margin without the sidenote mark.]{.column-margin} If you'd like to place ancillary information in the margin without the sidenote mark (the superscript number), you can use apply the `column-margin` class to the element.
142 | 
143 | # References
144 | 
145 | References can be displayed as margin notes for HTML output. For example, we can cite R here [@R-base].
146 | 
147 | ::: {.callout-note appearance="simple"}
148 | This feature depends upon `link-citations` to locate and place references in the margin. This is enabled by default, but if you disable `link-citations` then references in the HTML output will be placed at the end of the output document as they normally are.
149 | :::
150 | 
151 | # Tables
152 | 
153 | You can use the `kable()` function from the **knitr** package to format tables that integrate well with the rest of the Tufte handout style. The table captions are placed in the margin like figures in the HTML output.
154 | 
155 | ```{r}
156 | #| tbl-cap-location: margin
157 | knitr::kable(
158 |   mtcars[1:6, 1:6], caption = 'A subset of mtcars.'
159 | )
160 | ```
161 | 
162 | # Responsiveness
163 | 
164 | The HTML page layout is responsive- as the page width shrinks, elements will automatically adjust their position. Elements that appear in the margins will move inline with the content and elements that span the body and margin will automatically span only the body.
165 | 
166 | # More Examples
167 | 
168 | The rest of this document consists of a few test cases to make sure everything still works well in slightly more complicated scenarios. First we generate two plots in one figure environment with the chunk option `fig-show: hold`:
169 | 
170 | ```{r}
171 | #| label: fig-two-together
172 | #| fig-cap: "Two plots in one figure environment."
173 | #| fig-show: hold
174 | #| warning: false
175 | #| cap-location: margin
176 | p <- ggplot(mtcars2, aes(hp, mpg, color = am)) +
177 |   geom_point()
178 | p
179 | p + geom_smooth()
180 | ```
181 | 
182 | Then two plots in separate figure environments (the code is identical to the previous code chunk, but the chunk option is the default `fig-show: asis` now):
183 | 
184 | ```{r fig-two-separate, ref.label='fig-two-together', fig.cap=sprintf("Two plots in separate figure environments (the %s plot).", c("first", "second")), message=FALSE}
185 | #| cap-location: margin
186 | ```
187 | 
188 | You may have noticed that the two figures have different captions, and that is because we used a character vector of length 2 for the chunk option `fig.cap` (something like `fig.cap = c('first plot', 'second plot')`).
189 | 
190 | ::: {.callout-tip}
191 | ## Using R within Chunk Options
192 | If you wish to use raw R expressions as part of the chunk options (like above), then you need to define those in the `tag=value` format within the curly brackets `{r label, tag=value}` instead of the `tag: value` YAML syntax on a new line starting with the hashpipe `#|`. The former approach is documented on [knitr's website](https://yihui.org/knitr/options/) while the latter is explained in [Quarto's documentation](https://quarto.org/docs/reference/cells/cells-knitr.html).
193 | :::
194 | 
195 | Next we show multiple plots in margin figures. Similarly, two plots in the same figure environment in the margin:
196 | 
197 | ```{r}
198 | #| label: fig-margin-together
199 | #| fig-cap: "Two plots in one figure environment in the margin."
200 | #| fig-width: 3.5
201 | #| fig-height: 2
202 | #| fig-show: hold
203 | #| column: margin
204 | #| warning: false
205 | #| echo: false
206 | p
207 | p + geom_smooth(method = 'lm')
208 | ```
209 | 
210 | Then two plots from the same code chunk placed in different figure environments:
211 | 
212 | ```{r}
213 | #| echo: false
214 | knitr::kable(head(iris[,c(1,2,3,4)], 13))
215 | ```
216 | 
217 | ```{r}
218 | #| label: fig-margin-separate-a
219 | #| fig-cap: "Two plots in separate figure environments in the margin"
220 | #| fig-width: 3.5
221 | #| fig-height: 2
222 | #| column: margin
223 | #| warning: false
224 | #| echo: false
225 | p
226 | p + geom_smooth(method = 'lm')
227 | ```
228 | 
229 | ```{r}
230 | #| echo: false
231 | knitr::kable(head(iris[,c(1,2,3,4)], 11))
232 | ```
233 | 
234 | We blended some tables in the above code chunk only as *placeholders* to make sure there is enough vertical space among the margin figures, otherwise they will be stacked tightly together. For a practical document, you should not insert too many margin figures consecutively and make the margin crowded.
235 | 
236 | You do not have to assign captions to figures. We show three figures with no captions below in the margin, in the main column, and in full width, respectively.
237 | 
238 | ```{r}
239 | #| fig-width: 3.5
240 | #| fig-height: 2
241 | #| column: margin
242 | # a boxplot of weight vs transmission; this figure
243 | # will be placed in the margin
244 | ggplot(mtcars2, aes(am, wt)) + geom_boxplot() +
245 |   coord_flip()
246 | ```
247 | 
248 | ```{r}
249 | #| warning: false
250 | # a figure in the main column
251 | p <- ggplot(mtcars, aes(wt, hp)) + geom_point()
252 | p
253 | ```
254 | 
255 | ```{r}
256 | #| fig-width: 11
257 | #| fig-height: 4
258 | #| column: page-right
259 | #| warning: false
260 | # a fullwidth figure
261 | p + geom_smooth(method = 'lm') + facet_grid(~ gear)
262 | ```
263 | 
264 | # Some Notes on Page Layout
265 | 
266 | To see the Quarto markdown source of this example document, you may follow [this link to Github](https://raw.githubusercontent.com/quarto-dev/quarto-gallery/main/page-layout/tufte.qmd).
267 | 


--------------------------------------------------------------------------------
/presentations/beamer/beamer.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/beamer/beamer.pdf


--------------------------------------------------------------------------------
/presentations/beamer/beamer.qmd:
--------------------------------------------------------------------------------
 1 | ---
 2 | title: Pop Songs and Political Science
 3 | author: Steven V. Miller
 4 | institute: Department of Political Science
 5 | format: 
 6 |   beamer:
 7 |     navigation: horizontal
 8 |     header-includes: |
 9 |       \titlegraphic{\includegraphics[width=0.4\paperwidth]{clemson.png}}
10 | ---
11 | 
12 | ## Sheena Easton and Game Theory
13 | 
14 | Sheena Easton describes the following scenario for her baby:
15 | 
16 | 1.  Takes the morning train
17 | 2.  Works from nine 'til five
18 | 3.  Takes another train home again
19 | 4.  Finds Sheena Easton waiting for him
20 | 
21 | ## A Total Conflict Game Between Sheena Easton and Her Baby
22 | 
23 | |                        | Stays Home    | Goes to Work  |
24 | |------------------------|---------------|---------------|
25 | | **Baby Home Again**    | -100, **100** | **100**, 0    |
26 | | **Baby Stays at Work** | **50**, 0     | -100, **100** |
27 | 
28 | Sheena Easton and her baby are playing a **zero-sum (total conflict) game**.
29 | 
30 | -   Akin to Holmes-Moriarty game (see: von Neumann and Morgenstern)
31 | -   Solution: **mixed strategy**
32 | 
33 | ## Rick Astley's Re-election Platform
34 | 
35 | Rick Astley's campaign promises:
36 | 
37 | -   Never gonna give you up.
38 | -   Never gonna let you down.
39 | -   Never gonna run around and desert you.
40 | -   Never gonna make you cry.
41 | -   Never gonna say goodbye.
42 | -   Never gonna tell a lie and hurt you.
43 | 
44 | Are these promises (if credible) sufficient to secure re-election?
45 | 
46 | ## Rick Astley and Median Voter Theorem
47 | 
48 | Whereas these pledges conform to the preferences of the **median voter**, we expect Congressman Astley to secure re-election.
49 | 
50 | ## Caribbean Queen and Operation Urgent Fury
51 | 
52 | Billy Ocean released "Caribbean Queen" in 1984.
53 | 
54 | -   Emphasized sharing the same dream
55 | -   Hearts beating as one
56 | 
57 | "Caribbean Queen" is about the poor execution of Operation Urgent Fury.
58 | 
59 | -   Echoed JCS chairman David Jones' frustrations with military establishment.
60 | 
61 | Billy Ocean is advocating for what became the Goldwater-Nichols Act.
62 | 
63 | -   Wanted to take advantage of **economies of scale**, resolve **coordination problems** in U.S. military.
64 | 
65 | ## The Good Day Hypothesis
66 | 
67 | We know the following about Ice Cube's day.
68 | 
69 | 1.  The Lakers beat the Supersonics.
70 | 2.  No helicopter looked for a murder.
71 | 3.  Consumed Fatburger at 2 a.m.
72 | 4.  Goodyear blimp: "Ice Cube's a pimp."
73 | 
74 | ## The Good Day Hypothesis
75 | 
76 | This leads to two different hypotheses:
77 | 
78 | -   $H_0$: Ice Cube's day is statistically indistinguishable from a typical day.
79 | -   $H_1$: Ice Cube is having a good (i.e. greater than average) day.
80 | 
81 | These hypotheses are tested using archival data of Ice Cube's life.
82 | 


--------------------------------------------------------------------------------
/presentations/beamer/clemson.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/beamer/clemson.png


--------------------------------------------------------------------------------
/presentations/powerpoint/powerpoint.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/powerpoint/powerpoint.pptx


--------------------------------------------------------------------------------
/presentations/powerpoint/powerpoint.qmd:
--------------------------------------------------------------------------------
  1 | ---
  2 | title: "Best Practices for Administering RStudio in Production"
  3 | author: "Nathan Stephens"
  4 | format:
  5 |   pptx:
  6 |     reference-doc: template.pptx
  7 | ---
  8 | 
  9 | # Overview
 10 | 
 11 | ## Solutions engineering
 12 | 
 13 | ### We help you integrate RStudio products into your systems
 14 | 
 15 | ### Our team
 16 | 
 17 | ### Where do we hang out?
 18 | 
 19 | * [Community.rstudio.com](http://community.rstudio.com)
 20 | * [Github.com/sol-eng](http://)
 21 | * [Solutions.rstudio.com](http://solutions.rstudio.com)
 22 | * [Support.rstudio.com](http://support.rstudio.com)
 23 | * [Docs.rstudio.com](docs.rstudio.com)
 24 | 
 25 | ## Who is this webinar for?
 26 | 
 27 | ### R Admin -- data scientists who want to do more
 28 | 
 29 | ### R Evangelists
 30 | 
 31 | ### IT/Ops
 32 | 
 33 | ### Anyone who wants to try RStudio professional products
 34 | 
 35 | ## RStudio
 36 | 
 37 | ### RStudio empowers individuals to be productive with data science.
 38 | 
 39 | * Open source and reproducible research
 40 | * APIs and interoperability
 41 | * Usability and clear documentation
 42 | * Inclusive and collective success
 43 | * Creating lasting value for data science
 44 | 
 45 | ## What we do
 46 | 
 47 | ### RStudio builds open source and professional software for data science
 48 | 
 49 | * Our professional features include things like
 50 | 
 51 |     * Security
 52 |     * Authentication
 53 |     * Load balancing
 54 |     * Support
 55 | 
 56 | ### RStudio professional products
 57 | 
 58 | * RStudio Server Pro
 59 | * RStudio Connect
 60 | * RStudio Package Manager
 61 | 
 62 | 
 63 | ## What is the relationship between R and RStudio?
 64 | 
 65 | ### We don’t own R, package R, or distribute R
 66 | 
 67 | ### R Core team: 20 members -- Zero from RStudio
 68 | 
 69 | ### RStudio products "sit on top of R"
 70 | 
 71 |   * You standardize on R first
 72 |   * Install our products second
 73 |   
 74 | ### We assume you have chosen to invest in R
 75 | 
 76 | ## Professional R tooling and integration
 77 | 
 78 | ### Legitimacy
 79 | 
 80 | * Recognize R as an analytic standard
 81 | 
 82 | ### Competencies*
 83 | 
 84 | * Understand and manage R tooling
 85 | 
 86 | ### Adoption
 87 | 
 88 | * Rely on integrated R based solutions
 89 | 
 90 | 
 91 | ## Administering RStudio professional products
 92 | 
 93 | ### People want to know if they are doing things the best way
 94 | 
 95 | * R is relatively unknown in most organizations
 96 | * No single place to get all the information you need
 97 | * Hard to see the forest through the trees
 98 | 
 99 | ### We see a lot of trial and error
100 | 
101 | * Organizational hurdles
102 | * Resource limitations
103 | 
104 | ## Outline
105 | 
106 | ### I want to share some best practices for managing RStudio in production
107 | 
108 | * Share product requirements
109 | * Some tips
110 | * A path for getting started
111 | 
112 | Goal is to give you a big picture view of what success looks like, assuming you are using RStudio professional products
113 | 
114 | # 5 Best practices for administering RStudio in production
115 | 
116 | ## 1. Keep your system up to date
117 | 
118 | ### Modern tools
119 | 
120 |   * Operating system
121 |   * Browsers
122 |     
123 | ### C++11 compiler
124 | 
125 |   * R packages on Linux must be compiled
126 | 
127 | ### Internet access
128 |   
129 |   * R packages
130 |     
131 | ## 2. Support multiple versions of R
132 | 
133 | ### Why do you want to run multiple versions of R?
134 | 
135 |   * Manage upgrades of R
136 |   * Test code on a variety of R versions and distributions
137 |   * Support projects that depend on various versions of R
138 |   * All products support multiple versions of R
139 | 
140 | ### Upgrade yearly (version 3.1.0+)
141 | 
142 | ### Build R from source
143 | 
144 |   * Multiple versions of R side by side requires you build R from source
145 |   * Not hard to do (i.e. config/make/make install)
146 |   * [Instructions](https://support.rstudio.com/hc/en-us/articles/360002242413-Multiple-versions-of-R)
147 | 
148 | ## 3. Organize your R packages
149 | 
150 | ### R Packages rule the nest.
151 | 
152 | * Packages will drive your R version, Linux dependencies, and even your operating system
153 | * Data scientists will want access to their most beloved packages
154 | 
155 | ### Managing packages for a single user is easy. 
156 | 
157 | * Managing packages for an entire platform is hard
158 | 
159 | ### RStudio Package Manager solves several problems
160 | 
161 | * Disconnected, air-gapped environments
162 | * Curate packages into multiple repositories for security and control
163 | * Share internal packages
164 | 
165 | ## 4. Use root privileges
166 | 
167 | The group in your organization that installs, configures, and manages R and RStudio will need root privileges
168 | 
169 | ### RStudio products
170 | 
171 | * Installs require root privileges
172 | * Runs require root privileges
173 |     * RStudio Server Pro runs as the root user in order to create new R sessions on behalf of its users
174 |     * RStudio Connect runs as the root user in order to isolate applications and processes
175 | 
176 | ### R
177 | 
178 | * System-wide installations of R on Linux often involve root also
179 | 
180 | ## 5. Securely manage your users
181 | 
182 | ### R programmers - RStudio Server Pro
183 | 
184 | * They will need access to R, file shares, databases, and probably many other sensitive systems.
185 | * R processes run as the user under a local account
186 | 
187 | ### End users - RStudio Connect
188 | 
189 | * End users consume apps and reports.
190 | * R Processes typically run under a service account
191 | 
192 | ## Authentication
193 | 
194 | ### Your organization
195 | 
196 | * Probably has strong opinions on how to authenticate users
197 | * This space is only getting more fragmented not less
198 |     * LDAP, Active Directory, PAM, OAuth, Okta, Duo, Auth0, etc.
199 | 
200 | ### Proxied authentication
201 | 
202 | * If we don't support your specific system, then you can use our proxied authentication
203 | * With proxied auth, users do not log in through RStudio but through a proxy that you set up
204 | 
205 | ## Supported Auth Methods
206 | 
207 | ### RStudio Server Pro
208 | 
209 | * PAM (LDAP and Active Directory)
210 | * OAuth 2.0 using Google Apps
211 | * *Proxied authentication*
212 | 
213 | ### RStudio Connect
214 | 
215 | * LDAP and Active Directory
216 | * OAuth 2.0 using Google Apps
217 | * PAM
218 | * SAML [Beta]
219 | * *Proxied authentication*
220 | 
221 | ## Recommendations (your Happy path)
222 | 
223 | ### 1. Keep your operating systems and browsers up to date
224 | 
225 | ### 2. Plan to support multiple versions of R by building R from source
226 | 
227 | ### 3. Organize your R packages for reliability and consistency
228 | 
229 | ### 4. Use root privileges to install and run RStudio products
230 | 
231 | ### 5. Securely manage your R programmers and end users
232 | 
233 | # Getting Started
234 | 
235 | ## Tooling
236 | 
237 | ### RStudio makes software tools that are designed to work together
238 | 
239 | * Our R packages and products work together
240 | * There are many ways to assemble our tools
241 | * But it will be up to you to decide how to do it
242 | * Your configuration depends on what does data science means to your organization
243 | 
244 | Our goal is to make it easy to install and configure all of our products
245 | 
246 | ## Solutions
247 | 
248 | ### Data science lab
249 | 
250 | ### Application factories (Dev/Test/Prod)
251 | 
252 | ### On premises, cloud, hybrid cloud
253 | 
254 | ### Single server or a multi-departmental deployment
255 | 
256 | ### Crawl, walk, run strategies
257 | 
258 | ## Architecture
259 | 
260 | ![](ref-arch.png)
261 | 
262 | ## Server Setup
263 | 
264 | ![](servers.png)
265 | 
266 | ## Recipes
267 | 
268 | ### Overview
269 | 
270 | * List of ingredients that make up your platform
271 | * Helps you organize and automate your work
272 | * And are unique to your organization
273 | 
274 | ### Structure
275 | 
276 | * Most of your code will be for Linux, R, and R packages
277 | * A small part of your code will be for installation
278 | * If you've installed R properly, installation is usually easy
279 | * The rest will be configuration
280 | 
281 | ## Infrastructure as code
282 | 
283 | ### Organize your recipes so that can manage your platform
284 | 
285 | * [Configuration management tools for the R admin](https://resources.rstudio.com/rstudio-server-pro/configuration-management-tools-for-the-r-admin)
286 | * Ansible, Chef, Puppet, CodeDeploy, SaltStack, etc.
287 | * Sandbox
288 | 
289 | # What if I've never used these products?
290 | 
291 | ## RStudio Quickstart
292 | 
293 | ### Overview
294 | 
295 | * A virtual machine that runs on your desktop
296 | * Includes all our professional products
297 | * And includes pre built assets for you to explore and demonstrate to others
298 | 
299 | ### Motivation
300 | 
301 | * Experience RStudio professional products
302 | * Free and easy
303 | 
304 | [Demo](https://www.rstudio.com/products/quickstart/)
305 | 
306 | ## Summary
307 | 
308 | ### The happy path
309 | 
310 | * Keep your operating system and browser up to date
311 | * Support multiple versions of R by building R from source
312 | * Make sure you have easy access to R packages
313 | * Install products as root
314 | * Use a supported authentication system
315 | 
316 | ### How to get started
317 | 
318 | * Recipes and [checklists](https://support.rstudio.com/hc/en-us/articles/360015079054)
319 | * Crawl/Walk/Run strategies
320 | * [RStudio QuickStart](https://www.rstudio.com/products/quickstart/)
321 | 
322 | ## Summary
323 | 
324 | ### Connecting with solutions engineering
325 | 
326 | * [Community.rstudio.com](https://community.rstudio.com/)
327 | * [Github.com/sol-eng](http://)
328 | * [Solutions.rstudio.com](http://solutions.rstudio.com)
329 | * [Support.rstudio.com](http://support.rstudio.com)
330 | * [Docs.rstudio.com](docs.rstudio.com)
331 | 
332 | ## References
333 | 
334 | [Administration of Pro Products](https://resources.rstudio.com/administration-of-pro-products)
335 | 
336 | [Professional R Tooling and Integration](https://resources.rstudio.com/webinars/2018-07-11-13-00-professional-r-tooling-and-integration-nathan-stephens-1)
337 | 
338 | [The R Admin is Rad](https://resources.rstudio.com/rstudio-conf-2018/the-r-admin-is-rad-a-guide-to-professional-r-tooling-and-integration-nathan-stephens)
339 | 
340 | [R Admin Community](https://community.rstudio.com/c/r-admin)
341 | 
342 | [RStudio Docs](https://docs.rstudio.com/resources.html)
343 | 
344 | [RStudio Professional Product Requirements](https://support.rstudio.com/hc/en-us/articles/360015177453-RStudio-professional-product-requirements)
345 | 
346 | [RStudio Server Pro Example Checklist](https://support.rstudio.com/hc/en-us/articles/360015079054-RStudio-Server-Pro-Installation-and-Configuration-Example-Checklist)
347 | 
348 | [R for the Enterprise](https://rviews.rstudio.com/categories/r-for-the-enterprise/)
349 | 
350 | [Configuration Management Tools for the R Admin](https://resources.rstudio.com/rstudio-server-pro/configuration-management-tools-for-the-r-admin)
351 | 
352 | 
353 | 


--------------------------------------------------------------------------------
/presentations/powerpoint/ref-arch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/powerpoint/ref-arch.png


--------------------------------------------------------------------------------
/presentations/powerpoint/servers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/powerpoint/servers.png


--------------------------------------------------------------------------------
/presentations/powerpoint/template.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/powerpoint/template.pptx


--------------------------------------------------------------------------------
/presentations/revealjs/README.md:
--------------------------------------------------------------------------------
1 | ## Reveal.js presentation
2 | 
3 | 


--------------------------------------------------------------------------------
/presentations/revealjs/image/background_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/background_1.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/background_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/background_2.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/division_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/division_1.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/division_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/division_2.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/documentation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/documentation.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/efficiency.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/efficiency.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/format_1_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/format_1_1.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/format_1_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/format_1_2.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/format_1_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/format_1_3.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/format_1_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/format_1_4.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/format_2_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/format_2_1.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/format_2_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/format_2_2.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/format_2_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/format_2_3.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/format_2_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/format_2_4.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/gif_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/gif_0.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/gif_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/gif_1.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/gif_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/gif_2.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/gif_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/gif_3.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/gif_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/gif_4.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/gif_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/gif_5.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/gif_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/gif_6.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/gif_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/gif_7.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/gif_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/gif_8.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/gif_9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/gif_9.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/icjia.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/icjia.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/il_seal.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/il_seal.gif


--------------------------------------------------------------------------------
/presentations/revealjs/image/interface.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/interface.gif


--------------------------------------------------------------------------------
/presentations/revealjs/image/modularity_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/modularity_1.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/modularity_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/modularity_2.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/process_new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/process_new.png


--------------------------------------------------------------------------------
/presentations/revealjs/image/process_old.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/process_old.png


--------------------------------------------------------------------------------
/presentations/revealjs/requirements.txt:
--------------------------------------------------------------------------------
1 | jupyter
2 | 


--------------------------------------------------------------------------------
/presentations/revealjs/reveal.qmd:
--------------------------------------------------------------------------------
  1 | ---
  2 | title: "Modernizing R&A Data Products With Python"
  3 | author: "Bobae Kang and Yizi (Winnie) Huang
Center for Criminal Justice Data and Analytics" 4 | date: "R&A Staff Meeting
August 14, 2018" 5 | format: 6 | revealjs: 7 | theme: white 8 | center: true 9 | transition: slide 10 | incremental: false 11 | slide-level: 2 12 | navigationMode: linear 13 | self-contained: true 14 | --- 15 | 16 | ```{=html} 17 | 23 | ``` 24 | 25 | ## Agenda {transition="zoom"} 26 | 27 | > - Background 28 | > - Design and Implementation 29 | > - Showcase 30 | > - Path forward 31 | 32 | # Background {background="#466c8c"} 33 | 34 | ## {transition="concave-in fade-out"} 35 | 36 | ![](image/background_1.png){width="70%"} 37 | 38 | ## {transition="fade-in concave-out"} 39 | 40 | ![](image/background_2.png){width="70%"} 41 | 42 | ## 43 | 44 | ![](image/format_1_1.png){width="75%"} 45 | 46 | ## 47 | 48 | ![](image/process_old.png){width="75%"} 49 | 50 | ## Motivation 51 | 52 | - Time-consuming 53 | - Difficult to maintain 54 | - Suboptimal tools 55 | - Outmoded data format 56 | - Overreliance on a single individual 57 | 58 | 59 | # Design and implementation {background="#466c8c"} 60 | 61 | ## What we did 62 | 63 | - Automation 64 | - Modular and flexible design 65 | - Fast and efficient tools 66 | - Machine-friendly format 67 | - Potential division of labor 68 | 69 | ## Automation 70 | 71 | ![](https://media.giphy.com/media/3ohuPqvqWs2pFkeure/giphy.gif){width="60%"} 72 | 73 | ## Modularity {transition="concave-in fade-out"} 74 | 75 | ![](image/modularity_1.png){width="60%"} 76 | 77 | ## Modularity {transition="fade-in concave-out"} 78 | 79 | ![](image/modularity_2.png){width="60%"} 80 | 81 | ## Efficiency 82 | 83 | ![](image/efficiency.png){width="75%"} 84 | 85 | ## Format (old) {transition="concave-in fade-out"} 86 | 87 | ![](image/format_1_1.png){width="75%"} 88 | 89 | ## Format (old) {transition="fade"} 90 | 91 | ![](image/format_1_2.png){width="75%"} 92 | 93 | ## Format (old) {transition="fade"} 94 | 95 | ![](image/format_1_3.png){width="75%"} 96 | 97 | ## Format (old) {transition="fade-in concave-out"} 98 | 99 | ![](image/format_1_4.png){width="75%"} 100 | 101 | ## Format (new) {transition="concave-in fade-out"} 102 | 103 | ![](image/format_2_1.png){width="75%"} 104 | 105 | ## Format (new) {transition="fade"} 106 | 107 | ![](image/format_2_2.png){width="75%"} 108 | 109 | ## Format (new) {transition="fade-in concave-out"} 110 | 111 | ![](image/format_2_3.png){width="75%"} 112 | 113 | ## Format (new) 114 | 115 | ![](image/format_2_4.png){width="70%"} 116 | 117 | ## Division of labor {transition="concave-in fade-out"} 118 | 119 | ![](image/division_1.png){width="60%"} 120 | 121 | ## Division of labor {transition="fade-in concave-out"} 122 | 123 | ![](image/division_2.png){width="60%"} 124 | 125 | ## 126 | 127 | ![](image/process_new.png){width="70%"} 128 | 129 | # Showcase {background="#466c8c"} 130 | 131 | ## 132 | 133 | ![](image/interface.gif){width="70%"} 134 | 135 | ## 136 | 137 | [![](image/documentation.png){width="70%"}](https://bobaekang.github.io/icjia-web-dataset-maintenance-tool/) 138 | 139 | # Path forward {background="#466c8c"} 140 | 141 | # Thank you! 142 | -------------------------------------------------------------------------------- /presentations/revealjs/rsconnect/documents/reveal.qmd/rpubs.com/rpubs/Document.dcf: -------------------------------------------------------------------------------- 1 | name: Document 2 | title: 3 | username: 4 | account: rpubs 5 | server: rpubs.com 6 | hostUrl: rpubs.com 7 | appId: https://api.rpubs.com/api/v1/document/799576/7997c4a7f70b4662a46da9e666bda906 8 | bundleId: https://api.rpubs.com/api/v1/document/799576/7997c4a7f70b4662a46da9e666bda906 9 | url: http://rpubs.com/publish/claim/799576/df06d8d83bd241c6b19a89a6a6e7ea47 10 | when: 1629076119.00407 11 | lastSyncTime: 1629076119.00408 12 | -------------------------------------------------------------------------------- /quarto-gallery.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: pdfLaTeX 14 | --------------------------------------------------------------------------------