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<!--  --> 254<!-- ::: --> 255<!-- ::: {.g-col-12 .g-col-md-10} --> 256<!-- [Fall 2024](https://www.google.com), [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<!--  --> 264<!-- ::: --> 265<!-- ::: {.g-col-12 .g-col-md-10} --> 266<!-- [Spring 2025](https://www.google.com), [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<!--  --> 274<!-- ::: --> 275<!-- ::: {.g-col-12 .g-col-md-10} --> 276<!-- [Spring 2025](https://www.google.com), [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 864 </div> 865 <div class="nav-footer-right"> 866 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.