PageSourceSearch

https://tnagler.github.io/teaching.html

html tnagler.github.io collected 2026-10-03 10:05:20 UTC 32,912 bytes, 874 lines download raw bytes

1<!DOCTYPE html>
2<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
3
4<meta charset="utf-8">
5<meta name="generator" content="quarto-1.5.57">
6
7<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
8
9<meta name="author" content="Thomas Nagler">
10<meta name="description" content="Personal website of Thomas Nagler">
11
12<title>Teaching – Thomas Nagler</title>
13<style>
14code{white-space: pre-wrap;}
15span.smallcaps{font-variant: small-caps;}
16div.columns{display: flex; gap: min(4vw, 1.5em);}
17div.column{flex: auto; overflow-x: auto;}
18div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
19ul.task-list{list-style: none;}
20ul.task-list li input[type="checkbox"] {
21  width: 0.8em;
22  margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */ 
23  vertical-align: middle;
24}
25</style>
26
27
28<script src="site_libs/quarto-nav/quarto-nav.js"></script>
vendor: 1 bytes, line 28
28
29<script src="site_libs/quarto-nav/headroom.min.js"></script>
vendor: 1 bytes, line 29
29
30<script src="site_libs/clipboard/clipboard.min.js"></script>
vendor: 1 bytes, line 30
30
31<script src="site_libs/quarto-html/quarto.js"></script>
vendor: 1 bytes, line 31
31
32<script src="site_libs/quarto-html/popper.min.js"></script>
vendor: 1 bytes, line 32
32
33<script src="site_libs/quarto-html/tippy.umd.min.js"></script>
vendor: 1 bytes, line 33
33
34<script src="site_libs/quarto-html/anchor.min.js"></script>
34
35<link href="site_libs/quarto-html/tippy.css" rel="stylesheet">
36<link href="site_libs/quarto-html/quarto-syntax-highlighting.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-text-highlighting-styles">
37<link href="site_libs/quarto-html/quarto-syntax-highlighting-dark.css" rel="prefetch" class="quarto-color-scheme quarto-color-alternate" id="quarto-text-highlighting-styles">
38<script src="site_libs/bootstrap/bootstrap.min.js"></script>
38
39<link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
40<link href="site_libs/bootstrap/bootstrap.min.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-bootstrap" data-mode="light">
41<link href="site_libs/bootstrap/bootstrap-dark.min.css" rel="prefetch" class="quarto-color-scheme quarto-color-alternate" id="quarto-bootstrap" data-mode="dark">
42<script id="quarto-search-options" type="application/json">{
43  "language": {
44    "search-no-results-text": "No results",
45    "search-matching-documents-text": "matching documents",
46    "search-copy-link-title": "Copy link to search",
47    "search-hide-matches-text": "Hide additional matches",
48    "search-more-match-text": "more match in this document",
49    "search-more-matches-text": "more matches in this document",
50    "search-clear-button-title": "Clear",
51    "search-text-placeholder": "",
52    "search-detached-cancel-button-title": "Cancel",
53    "search-submit-button-title": "Submit",
54    "search-label": "Search"
55  }
56}</script>
vendor: 1 bytes, line 56
56
57<script async="" src="https://www.googletagmanager.com/gtag/js?id="></script>
57
58
59<script type="text/javascript">
60
61window.dataLayer = window.dataLayer || [];
62function gtag(){dataLayer.push(arguments);}
63gtag('js', new Date());
64gtag('config', '', { 'anonymize_ip': true});
65</script>
65
66
67<!-- 
68Load Academicons v1: https://jpswalsh.github.io/academicons/
69-->
70<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/jpswalsh/academicons@1/css/academicons.min.css">
71
72<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
73
74
75<!---
76The following code are needed to show dimension citation and altmetrics.
77https://api.altmetric.com/embeds.html
78https://badge.dimensions.ai/
79--->
80
81<script type="text/javascript" src="https://d1bxh8uas1mnw7.cloudfront.net/assets/embed.js"></script>
81
82
83<script async="" src="https://badge.dimensions.ai/badge.js" charset="utf-8"></script>
83
84
85<script type="text/javascript" src="//cdn.plu.mx/widget-popup.js"></script>
85
86
87
88<link rel="stylesheet" href="styles.css">
89<meta property="og:title" content="Teaching – Thomas Nagler">
90<meta property="og:description" content="Personal website of Thomas Nagler">
91<meta property="og:image" content="https://quarto.org/quarto.png">
92<meta property="og:site_name" content="Thomas Nagler">
93<meta name="twitter:title" content="Teaching – Thomas Nagler">
94<meta name="twitter:description" content="Personal website of Thomas Nagler">
95<meta name="twitter:image" content="https://quarto.org/quarto.png">
96<meta name="twitter:card" content="summary_large_image">
97</head>
98
99<body class="nav-fixed">
100
101<div id="quarto-search-results"></div>
102  <header id="quarto-header" class="headroom fixed-top quarto-banner">
103    <nav class="navbar navbar-expand-lg " data-bs-theme="dark">
104      <div class="navbar-container container-fluid">
105      <div class="navbar-brand-container mx-auto">
106    <a class="navbar-brand" href="./index.html">
107    <span class="navbar-title">Thomas Nagler</span>
108    </a>
109  </div>
110          <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" role="menu" aria-expanded="false" aria-label="Toggle navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
111  <span class="navbar-toggler-icon"></span>
112</button>
113          <div class="collapse navbar-collapse" id="navbarCollapse">
114            <ul class="navbar-nav navbar-nav-scroll me-auto">
115  <li class="nav-item">
116    <a class="nav-link" href="./index.html"> 
117<span class="menu-text">About</span></a>
118  </li>  
119  <li class="nav-item">
120    <a class="nav-link" href="./publications.html"> 
121<span class="menu-text">Publications</span></a>
122  </li>  
123  <li class="nav-item">
124    <a class="nav-link" href="./software.html"> 
125<span class="menu-text">Software</span></a>
126  </li>  
127  <li class="nav-item">
128    <a class="nav-link active" href="./teaching.html" aria-current="page"> 
129<span class="menu-text">Teaching</span></a>
130  </li>  
131  <li class="nav-item">
132    <a class="nav-link" href="./people.html"> 
133<span class="menu-text">Team</span></a>
134  </li>  
135</ul>
136          </div> <!-- /navcollapse -->
137            <div class="quarto-navbar-tools">
138  <a href="" class="quarto-color-scheme-toggle quarto-navigation-tool  px-1" onclick="window.quartoToggleColorScheme(); return false;" title="Toggle dark mode"><i class="bi"></i></a>
139</div>
140      </div> <!-- /container-fluid -->
141    </nav>
142</header>
143<!-- content -->
144<header id="title-block-header" class="quarto-title-block default page-columns page-full">
145  <div class="quarto-title-banner page-columns page-full">
146    <div class="quarto-title column-body">
147      <h1 class="title">Teaching</h1>
148                      </div>
149  </div>
150    
151  
152  <div class="quarto-title-meta">
153
154      
155    
156      
157    </div>
158    
159  
160  </header><div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
161<!-- sidebar -->
162<!-- margin-sidebar -->
163    <div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
164        <nav id="TOC" role="doc-toc" class="toc-active">
165    <h2 id="toc-title">On this page</h2>
166   
167  <ul>
168  <li><a href="#current-courses" id="toc-current-courses" class="nav-link active" data-scroll-target="#current-courses">Current courses</a></li>
169  <li><a href="#lecture-notes" id="toc-lecture-notes" class="nav-link" data-scroll-target="#lecture-notes">Lecture notes</a></li>
170  <li><a href="#awards" id="toc-awards" class="nav-link" data-scroll-target="#awards">Awards</a></li>
171  <li><a href="#thesis-supervision" id="toc-thesis-supervision" class="nav-link" data-scroll-target="#thesis-supervision">Thesis supervision</a></li>
172  </ul>
173</nav>
174    </div>
175<!-- main -->
176<main class="content quarto-banner-title-block" id="quarto-document-content">
177
178
179
180
181
182<section id="current-courses" class="level2">
183<h2 class="anchored" data-anchor-id="current-courses">Current courses</h2>
184<ul>
185<li>Statistical Learning Theory (Summer)</li>
186<li>Methoden der Linearen Algebra in der Statistik (Summer)</li>
187<li>Mathematical Statistics (Winter)</li>
188<li>Seminar: Statistics of Extremes (Summer) <!-- - Fortgeschrittene Mathematische Methoden in der Statistik (Winter) --></li>
189</ul>
190<hr>
191</section>
192<section id="lecture-notes" class="level2">
193<h2 class="anchored" data-anchor-id="lecture-notes">Lecture notes</h2>
194<ul>
195<li><a href="files/static/mathstat-lmu-2024.pdf">Mathematical Statistics</a></li>
196<li><a href="files/static/slt-2024.pdf">Statistical Learning Theory</a></li>
197<li><a href="files/static/linalg-2024.pdf">Lineare Algebra (German)</a></li>
198<li><a href="files/static/stan-2020.pdf">Statistics for Astronomy and Physics students</a></li>
199</ul>
200<hr>
201</section>
202<section id="awards" class="level2">
203<h2 class="anchored" data-anchor-id="awards">Awards</h2>
204<!-- [Teacher of the Year 2020](https://www.universiteitleiden.nl/science-talents-and-discoveries/teacher-of-the-year-award/thomas-nagler),  -->
205<p>Teacher of the Year 2020, <em>Faculty of Science, Leiden University</em></p>
206<hr>
207</section>
208<section id="thesis-supervision" class="level2">
209<h2 class="anchored" data-anchor-id="thesis-supervision">Thesis supervision</h2>
210<p>My group is supervising theses at both BSc and MSc levels, on a wide range of topics. Our group’s primary interest is in developing statistical methods and studying their theoretical properties. Here’s a non-exhaustive list of areas of particular interest:</p>
211<ul>
212<li>Copulas and other dependence models</li>
213<li>Functional data analysis</li>
214<li>Time series</li>
215<li>Probabilistic machine learning</li>
216<li>Statistical learning theory</li>
217<li>Bootstrap, cross-validation, and other resampling methods</li>
218</ul>
219<p>
219Interested LMU students may send an email with a recent transcript and indication of their interests.</p>
220<section id="past-highlights" class="level4">
221<h4 class="anchored" data-anchor-id="past-highlights">Past highlights</h4>
222<p>A. Razawy: <a href="files/static/razawy-suffdr.pdf">Spline Based Estimation for Sufficient Dimension Reduction</a><br>
223D. Krüger: <a href="https://mediatum.ub.tum.de/node?id=1554813">General vine copula models for stationary multivariate time series</a><br>
224R. Weber: <a href="http://mediatum.ub.tum.de/node?id=1467381">Value at Risk Estimation with Subset Simulation</a><br>
225A. Kreuzer: <a href="https://mediatum.ub.tum.de/node?id=1338821">Analysing the spatial dependency among fire danger indices</a><br>
226A. Brauer: <a href="https://mediatum.ub.tum.de/doc/1342845/1342845.pdf">Kernel estimation of conditional copula densities</a></p>
227<!-- ## Past courses
228
229#### University of Lausanne (2023)
230
231- Actuarial Data Science
232
233#### TU Delft (2021-2022)
234
235- Time Series   
236- Linear Algebra for Computer Science and Engineering   
237- Calculus for Computer Science and Engineering   
238- Calculus I for Aerospace Engineering   
239
240
241#### Leiden University (2019-2021)
242
243- Advanced Statistical Computing    
244- Statistics for Astronomy and Physics students [[lecture notes]](files/static/stan-2020.pdf)   
245
246#### TU Munich (2019)
247
248- Nonparametric Statistical Learning  
249- TA for several courses and seminars -->
250<!-- ## Class 1 -->
251<!-- ::: {.grid} -->
252<!-- ::: {.g-col-12 .g-col-md-2} -->
253<!-- ![](files/images/placeholder1.jpg) -->
254<!-- ::: -->
255<!-- ::: {.g-col-12 .g-col-md-10} -->
256<!-- [Fall 2024](https://www.google.com), &nbsp; [Fall 2023](https://www.google.com) -->
257<!-- Class 1 introduction. -->
258<!-- ::: -->
259<!-- ::: -->
260<!-- ## Class 2 -->
261<!-- ::: {.grid} -->
262<!-- ::: {.g-col-12 .g-col-md-2} -->
263<!-- ![](files/images/placeholder2.JPG) -->
264<!-- ::: -->
265<!-- ::: {.g-col-12 .g-col-md-10} -->
266<!-- [Spring 2025](https://www.google.com), &nbsp; [Fall 2023](https://www.google.com) -->
267<!-- Class 2 introduction. -->
268<!-- ::: -->
269<!-- ::: -->
270<!-- ## Class 3 -->
271<!-- ::: {.grid} -->
272<!-- ::: {.g-col-12 .g-col-md-2} -->
273<!-- ![](files/images/placeholder3.JPG) -->
274<!-- ::: -->
275<!-- ::: {.g-col-12 .g-col-md-10} -->
276<!-- [Spring 2025](https://www.google.com), &nbsp; [Spring 2024](https://www.google.com) -->
277<!-- Class 3 introduction.  -->
278<!-- ::: -->
279<!-- ::: -->
280
281
282</section>
283</section>
284
285</main> <!-- /main -->
286<script id="quarto-html-after-body" type="application/javascript">
287window.document.addEventListener("DOMContentLoaded", function (event) {
288  const toggleBodyColorMode = (bsSheetEl) => {
289    const mode = bsSheetEl.getAttribute("data-mode");
290    const bodyEl = window.document.querySelector("body");
291    if (mode === "dark") {
292      bodyEl.classList.add("quarto-dark");
293      bodyEl.classList.remove("quarto-light");
294    } else {
295      bodyEl.classList.add("quarto-light");
296      bodyEl.classList.remove("quarto-dark");
297    }
298  }
299  const toggleBodyColorPrimary = () => {
300    const bsSheetEl = window.document.querySelector("link#quarto-bootstrap");
301    if (bsSheetEl) {
302      toggleBodyColorMode(bsSheetEl);
303    }
304  }
305  toggleBodyColorPrimary();  
306  const disableStylesheet = (stylesheets) => {
307    for (let i=0; i < stylesheets.length; i++) {
308      const stylesheet = stylesheets[i];
309      stylesheet.rel = 'prefetch';
310    }
311  }
312  const enableStylesheet = (stylesheets) => {
313    for (let i=0; i < stylesheets.length; i++) {
314      const stylesheet = stylesheets[i];
315      stylesheet.rel = 'stylesheet';
316    }
317  }
318  const manageTransitions = (selector, allowTransitions) => {
319    const els = window.document.querySelectorAll(selector);
320    for (let i=0; i < els.length; i++) {
321      const el = els[i];
322      if (allowTransitions) {
323        el.classList.remove('notransition');
324      } else {
325        el.classList.add('notransition');
326      }
327    }
328  }
329  const toggleGiscusIfUsed = (isAlternate, darkModeDefault) => {
330    const baseTheme = document.querySelector('#giscus-base-theme')?.value ?? 'light';
331    const alternateTheme = document.querySelector('#giscus-alt-theme')?.value ?? 'dark';
332    let newTheme = '';
333    if(darkModeDefault) {
334      newTheme = isAlternate ? baseTheme : alternateTheme;
335    } else {
336      newTheme = isAlternate ? alternateTheme : baseTheme;
337    }
338    const changeGiscusTheme = () => {
339      // From: https://github.com/giscus/giscus/issues/336
340      const sendMessage = (message) => {
341        const iframe = document.querySelector('iframe.giscus-frame');
342        if (!iframe) return;
343        iframe.contentWindow.postMessage({ giscus: message }, 'https://giscus.app');
344      }
345      sendMessage({
346        setConfig: {
347          theme: newTheme
348        }
349      });
350    }
351    const isGiscussLoaded = window.document.querySelector('iframe.giscus-frame') !== null;
352    if (isGiscussLoaded) {
353      changeGiscusTheme();
354    }
355  }
356  const toggleColorMode = (alternate) => {
357    // Switch the stylesheets
358    const alternateStylesheets = window.document.querySelectorAll('link.quarto-color-scheme.quarto-color-alternate');
359    manageTransitions('#quarto-margin-sidebar .nav-link', false);
360    if (alternate) {
361      enableStylesheet(alternateStylesheets);
362      for (const sheetNode of alternateStylesheets) {
363        if (sheetNode.id === "quarto-bootstrap") {
364          toggleBodyColorMode(sheetNode);
365        }
366      }
367    } else {
368      disableStylesheet(alternateStylesheets);
369      toggleBodyColorPrimary();
370    }
371    manageTransitions('#quarto-margin-sidebar .nav-link', true);
372    // Switch the toggles
373    const toggles = window.document.querySelectorAll('.quarto-color-scheme-toggle');
374    for (let i=0; i < toggles.length; i++) {
375      const toggle = toggles[i];
376      if (toggle) {
377        if (alternate) {
378          toggle.classList.add("alternate");     
379        } else {
380          toggle.classList.remove("alternate");
381        }
382      }
383    }
384    // Hack to workaround the fact that safari doesn't
385    // properly recolor the scrollbar when toggling (#1455)
386    if (navigator.userAgent.indexOf('Safari') > 0 && navigator.userAgent.indexOf('Chrome') == -1) {
387      manageTransitions("body", false);
388      window.scrollTo(0, 1);
389      setTimeout(() => {
390        window.scrollTo(0, 0);
391        manageTransitions("body", true);
392      }, 40);  
393    }
394  }
395  const isFileUrl = () => { 
396    return window.location.protocol === 'file:';
397  }
398  const hasAlternateSentinel = () => {  
399    let styleSentinel = getColorSchemeSentinel();
400    if (styleSentinel !== null) {
401      return styleSentinel === "alternate";
402    } else {
403      return false;
404    }
405  }
406  const setStyleSentinel = (alternate) => {
407    const value = alternate ? "alternate" : "default";
408    if (!isFileUrl()) {
409      window.localStorage.setItem("quarto-color-scheme", value);
410    } else {
411      localAlternateSentinel = value;
412    }
413  }
414  const getColorSchemeSentinel = () => {
415    if (!isFileUrl()) {
416      const storageValue = window.localStorage.getItem("quarto-color-scheme");
417      return storageValue != null ? storageValue : localAlternateSentinel;
418    } else {
419      return localAlternateSentinel;
420    }
421  }
422  const darkModeDefault = false;
423  let localAlternateSentinel = darkModeDefault ? 'alternate' : 'default';
424  // Dark / light mode switch
425  window.quartoToggleColorScheme = () => {
426    // Read the current dark / light value 
427    let toAlternate = !hasAlternateSentinel();
428    toggleColorMode(toAlternate);
429    setStyleSentinel(toAlternate);
430    toggleGiscusIfUsed(toAlternate, darkModeDefault);
431  };
432  // Ensure there is a toggle, if there isn't float one in the top right
433  if (window.document.querySelector('.quarto-color-scheme-toggle') === null) {
434    const a = window.document.createElement('a');
435    a.classList.add('top-right');
436    a.classList.add('quarto-color-scheme-toggle');
437    a.href = "";
438    a.onclick = function() { try { window.quartoToggleColorScheme(); } catch {} return false; };
439    const i = window.document.createElement("i");
440    i.classList.add('bi');
441    a.appendChild(i);
442    window.document.body.appendChild(a);
443  }
444  // Switch to dark mode if need be
445  if (hasAlternateSentinel()) {
446    toggleColorMode(true);
447  } else {
448    toggleColorMode(false);
449  }
450  const icon = "";
451  const anchorJS = new window.AnchorJS();
452  anchorJS.options = {
453    placement: 'right',
454    icon: icon
455  };
456  anchorJS.add('.anchored');
457  const isCodeAnnotation = (el) => {
458    for (const clz of el.classList) {
459      if (clz.startsWith('code-annotation-')) {                     
460        return true;
461      }
462    }
463    return false;
464  }
465  const onCopySuccess = function(e) {
466    // button target
467    const button = e.trigger;
468    // don't keep focus
469    button.blur();
470    // flash "checked"
471    button.classList.add('code-copy-button-checked');
472    var currentTitle = button.getAttribute("title");
473    button.setAttribute("title", "Copied!");
474    let tooltip;
475    if (window.bootstrap) {
476      button.setAttribute("data-bs-toggle", "tooltip");
477      button.setAttribute("data-bs-placement", "left");
478      button.setAttribute("data-bs-title", "Copied!");
479      tooltip = new bootstrap.Tooltip(button, 
480        { trigger: "manual", 
481          customClass: "code-copy-button-tooltip",
482          offset: [0, -8]});
483      tooltip.show();    
484    }
485    setTimeout(function() {
486      if (tooltip) {
487        tooltip.hide();
488        button.removeAttribute("data-bs-title");
489        button.removeAttribute("data-bs-toggle");
490        button.removeAttribute("data-bs-placement");
491      }
492      button.setAttribute("title", currentTitle);
493      button.classList.remove('code-copy-button-checked');
494    }, 1000);
495    // clear code selection
496    e.clearSelection();
497  }
498  const getTextToCopy = function(trigger) {
499      const codeEl = trigger.previousElementSibling.cloneNode(true);
500      for (const childEl of codeEl.children) {
501        if (isCodeAnnotation(childEl)) {
502          childEl.remove();
503        }
504      }
505      return codeEl.innerText;
506  }
507  const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', {
508    text: getTextToCopy
509  });
510  clipboard.on('success', onCopySuccess);
511  if (window.document.getElementById('quarto-embedded-source-code-modal')) {
512    // For code content inside modals, clipBoardJS needs to be initialized with a container option
513    // TODO: Check when it could be a function (https://github.com/zenorocha/clipboard.js/issues/860)
514    const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', {
515      text: getTextToCopy,
516      container: window.document.getElementById('quarto-embedded-source-code-modal')
517    });
518    clipboardModal.on('success', onCopySuccess);
519  }
520    var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//);
521    var mailtoRegex = new RegExp(/^mailto:/);
522      var filterRegex = new RegExp("^(?:http:|https:)\/\/drganghe\.github\.io\/custom");
523    var isInternal = (href) => {
524        return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href);
525    }
526    // Inspect non-navigation links and adorn them if external
527 	var links = window.document.querySelectorAll('a[href]:not(.nav-link):not(.navbar-brand):not(.toc-action):not(.sidebar-link):not(.sidebar-item-toggle):not(.pagination-link):not(.no-external):not([aria-hidden]):not(.dropdown-item):not(.quarto-navigation-tool):not(.about-link)');
528    for (var i=0; i<links.length; i++) {
529      const link = links[i];
530      if (!isInternal(link.href)) {
531        // undo the damage that might have been done by quarto-nav.js in the case of
532        // links that we want to consider external
533        if (link.dataset.originalHref !== undefined) {
534          link.href = link.dataset.originalHref;
535        }
536          // target, if specified
537          link.setAttribute("target", "_blank");
538          if (link.getAttribute("rel") === null) {
539            link.setAttribute("rel", "noopener");
540          }
541      }
542    }
543  function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
544    const config = {
545      allowHTML: true,
546      maxWidth: 500,
547      delay: 100,
548      arrow: false,
549      appendTo: function(el) {
550          return el.parentElement;
551      },
552      interactive: true,
553      interactiveBorder: 10,
554      theme: 'quarto',
555      placement: 'bottom-start',
556    };
557    if (contentFn) {
558      config.content = contentFn;
559    }
560    if (onTriggerFn) {
561      config.onTrigger = onTriggerFn;
562    }
563    if (onUntriggerFn) {
564      config.onUntrigger = onUntriggerFn;
565    }
566    window.tippy(el, config); 
567  }
568  const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
569  for (var i=0; i<noterefs.length; i++) {
570    const ref = noterefs[i];
571    tippyHover(ref, function() {
572      // use id or data attribute instead here
573      let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
574      try { href = new URL(href).hash; } catch {}
575      const id = href.replace(/^#\/?/, "");
576      const note = window.document.getElementById(id);
577      if (note) {
578        return note.innerHTML;
579      } else {
580        return "";
581      }
582    });
583  }
584  const xrefs = window.document.querySelectorAll('a.quarto-xref');
585  const processXRef = (id, note) => {
586    // Strip column container classes
587    const stripColumnClz = (el) => {
588      el.classList.remove("page-full", "page-columns");
589      if (el.children) {
590        for (const child of el.children) {
591          stripColumnClz(child);
592        }
593      }
594    }
595    stripColumnClz(note)
596    if (id === null || id.startsWith('sec-')) {
597      // Special case sections, only their first couple elements
598      const container = document.createElement("div");
599      if (note.children && note.children.length > 2) {
600        container.appendChild(note.children[0].cloneNode(true));
601        for (let i = 1; i < note.children.length; i++) {
602          const child = note.children[i];
603          if (child.tagName === "P" && child.innerText === "") {
604            continue;
605          } else {
606            container.appendChild(child.cloneNode(true));
607            break;
608          }
609        }
610        if (window.Quarto?.typesetMath) {
611          window.Quarto.typesetMath(container);
612        }
613        return container.innerHTML
614      } else {
615        if (window.Quarto?.typesetMath) {
616          window.Quarto.typesetMath(note);
617        }
618        return note.innerHTML;
619      }
620    } else {
621      // Remove any anchor links if they are present
622      const anchorLink = note.querySelector('a.anchorjs-link');
623      if (anchorLink) {
624        anchorLink.remove();
625      }
626      if (window.Quarto?.typesetMath) {
627        window.Quarto.typesetMath(note);
628      }
629      // TODO in 1.5, we should make sure this works without a callout special case
630      if (note.classList.contains("callout")) {
631        return note.outerHTML;
632      } else {
633        return note.innerHTML;
634      }
635    }
636  }
637  for (var i=0; i<xrefs.length; i++) {
638    const xref = xrefs[i];
639    tippyHover(xref, undefined, function(instance) {
640      instance.disable();
641      let url = xref.getAttribute('href');
642      let hash = undefined; 
643      if (url.startsWith('#')) {
644        hash = url;
645      } else {
646        try { hash = new URL(url).hash; } catch {}
647      }
648      if (hash) {
649        const id = hash.replace(/^#\/?/, "");
650        const note = window.document.getElementById(id);
651        if (note !== null) {
652          try {
653            const html = processXRef(id, note.cloneNode(true));
654            instance.setContent(html);
655          } finally {
656            instance.enable();
657            instance.show();
658          }
659        } else {
660          // See if we can fetch this
661          fetch(url.split('#')[0])
662          .then(res => res.text())
663          .then(html => {
664            const parser = new DOMParser();
665            const htmlDoc = parser.parseFromString(html, "text/html");
666            const note = htmlDoc.getElementById(id);
667            if (note !== null) {
668              const html = processXRef(id, note);
669              instance.setContent(html);
670            } 
671          }).finally(() => {
672            instance.enable();
673            instance.show();
674          });
675        }
676      } else {
677        // See if we can fetch a full url (with no hash to target)
678        // This is a special case and we should probably do some content thinning / targeting
679        fetch(url)
680        .then(res => res.text())
681        .then(html => {
682          const parser = new DOMParser();
683          const htmlDoc = parser.parseFromString(html, "text/html");
684          const note = htmlDoc.querySelector('main.content');
685          if (note !== null) {
686            // This should only happen for chapter cross references
687            // (since there is no id in the URL)
688            // remove the first header
689            if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
690              note.children[0].remove();
691            }
692            const html = processXRef(null, note);
693            instance.setContent(html);
694          } 
695        }).finally(() => {
696          instance.enable();
697          instance.show();
698        });
699      }
700    }, function(instance) {
701    });
702  }
703      let selectedAnnoteEl;
704      const selectorForAnnotation = ( cell, annotation) => {
705        let cellAttr = 'data-code-cell="' + cell + '"';
706        let lineAttr = 'data-code-annotation="' +  annotation + '"';
707        const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
708        return selector;
709      }
710      const selectCodeLines = (annoteEl) => {
711        const doc = window.document;
712        const targetCell = annoteEl.getAttribute("data-target-cell");
713        const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
714        const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
715        const lines = annoteSpan.getAttribute("data-code-lines").split(",");
716        const lineIds = lines.map((line) => {
717          return targetCell + "-" + line;
718        })
719        let top = null;
720        let height = null;
721        let parent = null;
722        if (lineIds.length > 0) {
723            //compute the position of the single el (top and bottom and make a div)
724            const el = window.document.getElementById(lineIds[0]);
725            top = el.offsetTop;
726            height = el.offsetHeight;
727            parent = el.parentElement.parentElement;
728          if (lineIds.length > 1) {
729            const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
730            const bottom = lastEl.offsetTop + lastEl.offsetHeight;
731            height = bottom - top;
732          }
733          if (top !== null && height !== null && parent !== null) {
734            // cook up a div (if necessary) and position it 
735            let div = window.document.getElementById("code-annotation-line-highlight");
736            if (div === null) {
737              div = window.document.createElement("div");
738              div.setAttribute("id", "code-annotation-line-highlight");
739              div.style.position = 'absolute';
740              parent.appendChild(div);
741            }
742            div.style.top = top - 2 + "px";
743            div.style.height = height + 4 + "px";
744            div.style.left = 0;
745            let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
746            if (gutterDiv === null) {
747              gutterDiv = window.document.createElement("div");
748              gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
749              gutterDiv.style.position = 'absolute';
750              const codeCell = window.document.getElementById(targetCell);
751              const gutter = codeCell.querySelector('.code-annotation-gutter');
752              gutter.appendChild(gutterDiv);
753            }
754            gutterDiv.style.top = top - 2 + "px";
755            gutterDiv.style.height = height + 4 + "px";
756          }
757          selectedAnnoteEl = annoteEl;
758        }
759      };
760      const unselectCodeLines = () => {
761        const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
762        elementsIds.forEach((elId) => {
763          const div = window.document.getElementById(elId);
764          if (div) {
765            div.remove();
766          }
767        });
768        selectedAnnoteEl = undefined;
769      };
770        // Handle positioning of the toggle
771    window.addEventListener(
772      "resize",
773      throttle(() => {
774        elRect = undefined;
775        if (selectedAnnoteEl) {
776          selectCodeLines(selectedAnnoteEl);
777        }
778      }, 10)
779    );
780    function throttle(fn, ms) {
781    let throttle = false;
782    let timer;
783      return (...args) => {
784        if(!throttle) { // first call gets through
785            fn.apply(this, args);
786            throttle = true;
787        } else { // all the others get throttled
788            if(timer) clearTimeout(timer); // cancel #2
789            timer = setTimeout(() => {
790              fn.apply(this, args);
791              timer = throttle = false;
792            }, ms);
793        }
794      };
795    }
796      // Attach click handler to the DT
797      const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
798      for (const annoteDlNode of annoteDls) {
799        annoteDlNode.addEventListener('click', (event) => {
800          const clickedEl = event.target;
801          if (clickedEl !== selectedAnnoteEl) {
802            unselectCodeLines();
803            const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
804            if (activeEl) {
805              activeEl.classList.remove('code-annotation-active');
806            }
807            selectCodeLines(clickedEl);
808            clickedEl.classList.add('code-annotation-active');
809          } else {
810            // Unselect the line
811            unselectCodeLines();
812            clickedEl.classList.remove('code-annotation-active');
813          }
814        });
815      }
816  const findCites = (el) => {
817    const parentEl = el.parentElement;
818    if (parentEl) {
819      const cites = parentEl.dataset.cites;
820      if (cites) {
821        return {
822          el,
823          cites: cites.split(' ')
824        };
825      } else {
826        return findCites(el.parentElement)
827      }
828    } else {
829      return undefined;
830    }
831  };
832  var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
833  for (var i=0; i<bibliorefs.length; i++) {
834    const ref = bibliorefs[i];
835    const citeInfo = findCites(ref);
836    if (citeInfo) {
837      tippyHover(citeInfo.el, function() {
838        var popup = window.document.createElement('div');
839        citeInfo.cites.forEach(function(cite) {
840          var citeDiv = window.document.createElement('div');
841          citeDiv.classList.add('hanging-indent');
842          citeDiv.classList.add('csl-entry');
843          var biblioDiv = window.document.getElementById('ref-' + cite);
844          if (biblioDiv) {
845            citeDiv.innerHTML = biblioDiv.innerHTML;
846          }
847          popup.appendChild(citeDiv);
848        });
849        return popup.innerHTML;
850      });
851    }
852  }
853});
854</script>
854
855</div> <!-- /content -->
856<footer class="footer">
857  <div class="nav-footer">
858    <div class="nav-footer-left">
859<a href="http://www.tnagler.com">Thomas Nagler</a> ©
860<script>document.write(new Date().getFullYear())</script>
860
861</div>   
862    <div class="nav-footer-center">
863      &nbsp;
864    </div>
865    <div class="nav-footer-right">
866      &nbsp;
867    </div>
868  </div>
869</footer>
870
871
872
873
874</body></html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.