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<!-- This site is hosted on Netlify. Anyone can build and deploy a site 6 like this one for free: https://netlify.new/?utm_campaign=loops&utm_source=ai-legible&utm_medium=owned&utm_content=comment&utm_id=af4360b4-4a70-4cbe-87f6-43fa708bbace 7 Netlify hosting facts for this site: static/SSR served via Netlify Edge. --> 8<meta name="generator" content="quarto-1.9.38"> 9 10<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 11 12<meta name="description" content="Dr. Caitlin Gradyâs teaching focuses on sustainability, environmental engineering, and policy modeling in complex systems."> 13 14<title>Teaching â FEWsLab</title> 15<style> 16/* Default styles provided by pandoc. 17** See https://pandoc.org/MANUAL.html#variables-for-html for config info. 18*/ 19code{white-space: pre-wrap;} 20span.smallcaps{font-variant: small-caps;} 21div.columns{display: flex; gap: min(4vw, 1.5em);} 22div.column{flex: auto; overflow-x: auto;} 23div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} 24ul.task-list{list-style: none;} 25ul.task-list li input[type="checkbox"] { 26 width: 0.8em; 27 margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */ 28 vertical-align: middle; 29} 30</style> 31 32
33<script src="site_libs/quarto-nav/quarto-nav.js"></script>
vendor: 1 bytes, line 33
33
34<script src="site_libs/quarto-nav/headroom.min.js"></script>
vendor: 1 bytes, line 34
34
35<script src="site_libs/clipboard/clipboard.min.js"></script>
vendor: 1 bytes, line 35
35
36<script src="site_libs/quarto-search/autocomplete.umd.js"></script>
vendor: 1 bytes, line 36
36
37<script src="site_libs/quarto-search/fuse.min.js"></script>
vendor: 1 bytes, line 37
37
38<script src="site_libs/quarto-search/quarto-search.js"></script>
38 39<meta name="quarto:offset" content="./"> 40<link href="./images/favicon/favicon.ico" rel="icon">
41<script src="site_libs/quarto-html/quarto.js" type="module"></script>
vendor: 1 bytes, line 41
41
42<script src="site_libs/quarto-html/tabsets/tabsets.js" type="module"></script>
vendor: 1 bytes, line 42
42
43<script src="site_libs/quarto-html/popper.min.js"></script>
vendor: 1 bytes, line 43
43
44<script src="site_libs/quarto-html/tippy.umd.min.js"></script>
vendor: 1 bytes, line 44
44
45<script src="site_libs/quarto-html/anchor.min.js"></script>
45 46<link href="site_libs/quarto-html/tippy.css" rel="stylesheet"> 47<link href="site_libs/quarto-html/quarto-syntax-highlighting-15634bcf2e68342d4ad2dfa704d543f6.css" rel="stylesheet" id="quarto-text-highlighting-styles">
48<script src="site_libs/bootstrap/bootstrap.min.js"></script>
48 49<link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet"> 50<link href="site_libs/bootstrap/bootstrap-22f1789df73c9a524649167e87525b34.min.css" rel="stylesheet" append-hash="true" id="quarto-bootstrap" data-mode="light">
51<script id="quarto-search-options" type="application/json">{ 52 "location": "navbar", 53 "copy-button": false, 54 "collapse-after": 3, 55 "panel-placement": "end", 56 "type": "overlay", 57 "limit": 50, 58 "keyboard-shortcut": [ 59 "f", 60 "/", 61 "s" 62 ], 63 "language": { 64 "search-no-results-text": "No results", 65 "search-matching-documents-text": "matching documents", 66 "search-copy-link-title": "Copy link to search", 67 "search-hide-matches-text": "Hide additional matches", 68 "search-more-match-text": "more match in this document", 69 "search-more-matches-text": "more matches in this document", 70 "search-clear-button-title": "Clear", 71 "search-text-placeholder": "", 72 "search-detached-cancel-button-title": "Cancel", 73 "search-submit-button-title": "Submit", 74 "search-label": "Search" 75 } 76}</script>
76 77<style>html{ scroll-behavior: smooth; }</style> 78<!-- academic icons --> 79 80<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/jpswalsh/academicons@1/css/academicons.min.css"> 81 82<!-- altmetric icons -->
83<script type="text/javascript" src="https://d1bxh8uas1mnw7.cloudfront.net/assets/embed.js"></script>
83 84 85<!-- fontawesome icons -->
86<script src="https://kit.fontawesome.com/1392a7030f.js" crossorigin="anonymous"></script>
86 87 88 89 90 91</head> 92 93<body class="floating nav-fixed quarto-light"> 94 95<div id="quarto-search-results"></div> 96 <header id="quarto-header" class="headroom fixed-top"> 97 <nav class="navbar navbar-expand-lg " data-bs-theme="dark"> 98 <div class="navbar-container container-fluid"> 99 <div class="navbar-brand-container mx-auto"> 100 <a class='navbar-brand' href='/'> 101 <span class="navbar-title">FEWsLab</span> 102 </a> 103 </div> 104 <div id="quarto-search" class="" title="Search"></div> 105 <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(); }"> 106 <span class="navbar-toggler-icon"></span> 107</button> 108 <div class="collapse navbar-collapse" id="navbarCollapse"> 109 <ul class="navbar-nav navbar-nav-scroll ms-auto"> 110 <li class="nav-item"> 111 <a class='nav-link' href='/about'> 112<span class="menu-text">About</span></a> 113 </li> 114 <li class="nav-item"> 115 <a class='nav-link' href='/lab'> 116<span class="menu-text">Team</span></a> 117 </li> 118 <li class="nav-item"> 119 <a class='nav-link' href='/research'> 120<span class="menu-text">News & Publications</span></a> 121 </li> 122 <li class="nav-item"> 123 <a aria-current='page' class='nav-link active' href='/teaching'> 124<span class="menu-text">Teaching</span></a> 125 </li> 126 <li class="nav-item"> 127 <a class='nav-link' href='/projects'> 128<span class="menu-text">Projects</span></a> 129 </li> 130</ul> 131 </div> <!-- /navcollapse --> 132 <div class="quarto-navbar-tools"> 133</div> 134 </div> <!-- /container-fluid --> 135 </nav> 136</header> 137<!-- content --> 138<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar"> 139<!-- sidebar --> 140 <nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal quarto-sidebar-collapse-item sidebar-navigation floating overflow-auto"> 141 <nav id="TOC" role="doc-toc" class="toc-active"> 142 <h2 id="toc-title">Courses</h2> 143 144 <ul> 145 <li><a href="#teaching-philosophy" id="toc-teaching-philosophy" class="nav-link active" data-scroll-target="#teaching-philosophy">Teaching Philosophy</a></li> 146 <li><a href="#current-course-instruction" id="toc-current-course-instruction" class="nav-link" data-scroll-target="#current-course-instruction">Current Course Instruction</a></li> 147 </ul> 148</nav> 149</nav> 150<div id="quarto-sidebar-glass" class="quarto-sidebar-collapse-item" data-bs-toggle="collapse" data-bs-target=".quarto-sidebar-collapse-item"></div> 151<!-- margin-sidebar --> 152 <div id="quarto-margin-sidebar" class="sidebar margin-sidebar zindex-bottom"> 153 </div> 154<!-- main --> 155<main class="content" id="quarto-document-content"> 156 157<header id="title-block-header" class="quarto-title-block default"> 158<div class="quarto-title"> 159<h1 class="title">Teaching</h1> 160</div> 161 162<div> 163 <div class="description"> 164 Dr. Caitlin Gradyâs teaching focuses on sustainability, environmental engineering, and policy modeling in complex systems. 165 </div> 166</div> 167 168 169<div class="quarto-title-meta"> 170 171 172 173 174 </div> 175 176 177 178</header> 179 180 181<section id="teaching-philosophy" class="level3"> 182<h3 class="anchored" data-anchor-id="teaching-philosophy">Teaching Philosophy</h3> 183<p>Dr. Gradyâs teaching interests include a variety of systems engineering, engineering design, and environmental policy courses. Her pedagogy blends active learning and problem-based learning approaches, combining student-centered instruction with real-world problems. These methods emphasize critical thinking and the application of technical knowledge to transdisciplinary topics.</p> 184<p>In recent years, she has taught and guest lectured in several courses, including:</p> 185<ul> 186<li>Global Environmental Politics<br> 187</li> 188<li>Communicating with Policymakers<br> 189</li> 190<li>Global Sustainable Engineering<br> 191</li> 192<li>Engineering Environmental Sustainability<br> 193</li> 194<li>Water & Wastewater Treatment<br> 195</li> 196<li>Introduction to Sustainable Water Resources<br> 197</li> 198<li>Introduction to Environmental Engineering</li> 199</ul> 200<hr> 201</section> 202<section id="current-course-instruction" class="level3"> 203<h3 class="anchored" data-anchor-id="current-course-instruction">Current Course Instruction</h3> 204<section id="emse-6740-systems-thinking-and-policy-modeling-i-3-credits" class="level4"> 205<h4 class="anchored">EMSE 6740: Systems Thinking and Policy Modeling I (3 Credits)</h4> 206<div class="grid"> 207<div class="g-col-9"> 208<p><strong>Institution</strong>: The George Washington University<br> 209<strong>Semester</strong>: Every Spring</p> 210<p>Policy analysis with applications to business management and public policy. Topics include causal-loop diagrams, stock and flow models of business, technology adoption, and marketing. The course incorporates role-based games to explore principles of systems thinking and uses simulation to analyze complex case studies.</p> 211<section id="emse-1001-introduction-to-systems-engineering-1-credit" class="level4"> 212<h4 class="anchored" data-anchor-id="emse-1001-introduction-to-systems-engineering-1-credit">EMSE 1001: Introduction to Systems Engineering (1 Credit)</h4> 213<div class="grid"> 214<div class="g-col-9"> 215<p><strong>Institution</strong>: The George Washington University<br> 216<strong>Semester</strong>: Every Fall</p> 217<p>Core concepts in systems engineering; processes of system decomposition and integration; upfront conceptual design, rapid prototyping, structured testing, balanced work, lean processes, and design for manufacturability.</p> 218</div> 219</div> 220<hr> 221</section> 222<section id="past-courses-taught" class="level3"> 223<h3 class="anchored" data-anchor-id="past-courses-taught">Past Courses Taught</h3> 224<section id="ce-360-fluid-mechanics" class="level4"> 225<h4 class="anchored" data-anchor-id="ce-360-fluid-mechanics">CE 360: Fluid Mechanics</h4> 226<div class="grid"> 227<div class="g-col-9"> 228<p><strong>Institution</strong>: Penn State University, University Park<br> 229<strong>Semesters</strong>: Fall 2017, Spring 2019, Spring 2020</p> 230</div> 231</div> 232</section> 233<section id="ce-597-ethics-engineering-and-environmental-management" class="level4"> 234<h4 class="anchored" data-anchor-id="ce-597-ethics-engineering-and-environmental-management">CE 597: Ethics, Engineering, and Environmental Management</h4> 235<div class="grid"> 236<div class="g-col-9"> 237<p><strong>Institution</strong>: Penn State University, University Park<br> 238<strong>Semesters</strong>: Spring 2018, Spring 2019, Spring 2020</p> 239</div> 240</div> 241<hr> 242</section> 243</section> 244<section id="research-to-advance-teaching" class="level3"> 245<h3 class="anchored" data-anchor-id="research-to-advance-teaching">Research to Advance Teaching</h3> 246<p><img src="images/teaching.png" class="img-fluid" style="width:100.0%"></p> 247<div class="grid"> 248<div class="g-col-9"> 249<p>Dr. Grady has secured <em>National Science Foundation</em> funding to advance understanding around teaching ethics. She is currently working on a multi-year award to develop engaged student learning through coupled ethical-epistemic pedagogy. More about the award can be found <a href="https://www.nsf.gov/awardsearch/showAward?AWD_ID=2314334&HistoricalAwards=false">here</a></p> 250</div> 251</div> 252 253 254</section> 255</div> 256</div> 257</section> 258</section> 259 260</main> <!-- /main -->
261<script id="quarto-html-after-body" type="application/javascript"> 262 window.document.addEventListener("DOMContentLoaded", function (event) { 263 const icon = "î§"; 264 const anchorJS = new window.AnchorJS(); 265 anchorJS.options = { 266 placement: 'right', 267 icon: icon 268 }; 269 anchorJS.add('.anchored'); 270 const isCodeAnnotation = (el) => { 271 for (const clz of el.classList) { 272 if (clz.startsWith('code-annotation-')) { 273 return true; 274 } 275 } 276 return false; 277 } 278 const onCopySuccess = function(e) { 279 // button target 280 const button = e.trigger; 281 // don't keep focus 282 button.blur(); 283 // flash "checked" 284 button.classList.add('code-copy-button-checked'); 285 var currentTitle = button.getAttribute("title"); 286 button.setAttribute("title", "Copied!"); 287 let tooltip; 288 if (window.bootstrap) { 289 button.setAttribute("data-bs-toggle", "tooltip"); 290 button.setAttribute("data-bs-placement", "left"); 291 button.setAttribute("data-bs-title", "Copied!"); 292 tooltip = new bootstrap.Tooltip(button, 293 { trigger: "manual", 294 customClass: "code-copy-button-tooltip", 295 offset: [0, -8]}); 296 tooltip.show(); 297 } 298 setTimeout(function() { 299 if (tooltip) { 300 tooltip.hide(); 301 button.removeAttribute("data-bs-title"); 302 button.removeAttribute("data-bs-toggle"); 303 button.removeAttribute("data-bs-placement"); 304 } 305 button.setAttribute("title", currentTitle); 306 button.classList.remove('code-copy-button-checked'); 307 }, 1000); 308 // clear code selection 309 e.clearSelection(); 310 } 311 const getTextToCopy = function(trigger) { 312 const outerScaffold = trigger.parentElement.cloneNode(true); 313 const codeEl = outerScaffold.querySelector('code'); 314 for (const childEl of codeEl.children) { 315 if (isCodeAnnotation(childEl)) { 316 childEl.remove(); 317 } 318 } 319 return codeEl.innerText; 320 } 321 const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', { 322 text: getTextToCopy 323 }); 324 clipboard.on('success', onCopySuccess); 325 if (window.document.getElementById('quarto-embedded-source-code-modal')) { 326 const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', { 327 text: getTextToCopy, 328 container: window.document.getElementById('quarto-embedded-source-code-modal') 329 }); 330 clipboardModal.on('success', onCopySuccess); 331 } 332 var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//); 333 var mailtoRegex = new RegExp(/^mailto:/); 334 var filterRegex = new RegExp("https:\/\/fewslab\.netlify\.app"); 335 var isInternal = (href) => { 336 return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href); 337 } 338 // Inspect non-navigation links and adorn them if external 339 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)'); 340 for (var i=0; i<links.length; i++) { 341 const link = links[i]; 342 if (!isInternal(link.href)) { 343 // undo the damage that might have been done by quarto-nav.js in the case of 344 // links that we want to consider external 345 if (link.dataset.originalHref !== undefined) { 346 link.href = link.dataset.originalHref; 347 } 348 // target, if specified 349 link.setAttribute("target", "_blank"); 350 if (link.getAttribute("rel") === null) { 351 link.setAttribute("rel", "noopener"); 352 } 353 } 354 } 355 function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) { 356 const config = { 357 allowHTML: true, 358 maxWidth: 500, 359 delay: 100, 360 arrow: false, 361 appendTo: function(el) { 362 return el.parentElement; 363 }, 364 interactive: true, 365 interactiveBorder: 10, 366 theme: 'quarto', 367 placement: 'bottom-start', 368 }; 369 if (contentFn) { 370 config.content = contentFn; 371 } 372 if (onTriggerFn) { 373 config.onTrigger = onTriggerFn; 374 } 375 if (onUntriggerFn) { 376 config.onUntrigger = onUntriggerFn; 377 } 378 window.tippy(el, config); 379 } 380 const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]'); 381 for (var i=0; i<noterefs.length; i++) { 382 const ref = noterefs[i]; 383 tippyHover(ref, function() { 384 // use id or data attribute instead here 385 let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href'); 386 try { href = new URL(href).hash; } catch {} 387 const id = href.replace(/^#\/?/, ""); 388 const note = window.document.getElementById(id); 389 if (note) { 390 return note.innerHTML; 391 } else { 392 return ""; 393 } 394 }); 395 } 396 const xrefs = window.document.querySelectorAll('a.quarto-xref'); 397 const processXRef = (id, note) => { 398 // Strip column container classes 399 const stripColumnClz = (el) => { 400 el.classList.remove("page-full", "page-columns"); 401 if (el.children) { 402 for (const child of el.children) {
403 stripColumnClz(child); 404 } 405 } 406 } 407 stripColumnClz(note) 408 if (id === null || id.startsWith('sec-')) { 409 // Special case sections, only their first couple elements 410 const container = document.createElement("div"); 411 if (note.children && note.children.length > 2) { 412 container.appendChild(note.children[0].cloneNode(true)); 413 for (let i = 1; i < note.children.length; i++) { 414 const child = note.children[i]; 415 if (child.tagName === "P" && child.innerText === "") { 416 continue; 417 } else { 418 container.appendChild(child.cloneNode(true)); 419 break; 420 } 421 } 422 if (window.Quarto?.typesetMath) { 423 window.Quarto.typesetMath(container); 424 } 425 return container.innerHTML 426 } else { 427 if (window.Quarto?.typesetMath) { 428 window.Quarto.typesetMath(note); 429 } 430 return note.innerHTML; 431 } 432 } else { 433 // Remove any anchor links if they are present 434 const anchorLink = note.querySelector('a.anchorjs-link'); 435 if (anchorLink) { 436 anchorLink.remove(); 437 } 438 if (window.Quarto?.typesetMath) { 439 window.Quarto.typesetMath(note); 440 } 441 if (note.classList.contains("callout")) { 442 return note.outerHTML; 443 } else { 444 return note.innerHTML; 445 } 446 } 447 } 448 for (var i=0; i<xrefs.length; i++) { 449 const xref = xrefs[i]; 450 tippyHover(xref, undefined, function(instance) { 451 instance.disable(); 452 let url = xref.getAttribute('href'); 453 let hash = undefined; 454 if (url.startsWith('#')) { 455 hash = url; 456 } else { 457 try { hash = new URL(url).hash; } catch {} 458 } 459 if (hash) { 460 const id = hash.replace(/^#\/?/, ""); 461 const note = window.document.getElementById(id); 462 if (note !== null) { 463 try { 464 const html = processXRef(id, note.cloneNode(true)); 465 instance.setContent(html); 466 } finally { 467 instance.enable(); 468 instance.show(); 469 } 470 } else { 471 // See if we can fetch this 472 fetch(url.split('#')[0]) 473 .then(res => res.text()) 474 .then(html => { 475 const parser = new DOMParser(); 476 const htmlDoc = parser.parseFromString(html, "text/html"); 477 const note = htmlDoc.getElementById(id); 478 if (note !== null) { 479 const html = processXRef(id, note); 480 instance.setContent(html); 481 } 482 }).finally(() => { 483 instance.enable(); 484 instance.show(); 485 }); 486 } 487 } else { 488 // See if we can fetch a full url (with no hash to target) 489 // This is a special case and we should probably do some content thinning / targeting 490 fetch(url) 491 .then(res => res.text()) 492 .then(html => { 493 const parser = new DOMParser(); 494 const htmlDoc = parser.parseFromString(html, "text/html"); 495 const note = htmlDoc.querySelector('main.content'); 496 if (note !== null) { 497 // This should only happen for chapter cross references 498 // (since there is no id in the URL) 499 // remove the first header 500 if (note.children.length > 0 && note.children[0].tagName === "HEADER") { 501 note.children[0].remove(); 502 } 503 const html = processXRef(null, note); 504 instance.setContent(html); 505 } 506 }).finally(() => { 507 instance.enable(); 508 instance.show(); 509 }); 510 } 511 }, function(instance) { 512 }); 513 } 514 let selectedAnnoteEl; 515 const selectorForAnnotation = ( cell, annotation) => { 516 let cellAttr = 'data-code-cell="' + cell + '"'; 517 let lineAttr = 'data-code-annotation="' + annotation + '"'; 518 const selector = 'span[' + cellAttr + '][' + lineAttr + ']'; 519 return selector; 520 } 521 const selectCodeLines = (annoteEl) => { 522 const doc = window.document; 523 const targetCell = annoteEl.getAttribute("data-target-cell"); 524 const targetAnnotation = annoteEl.getAttribute("data-target-annotation"); 525 const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation)); 526 const lines = annoteSpan.getAttribute("data-code-lines").split(","); 527 const lineIds = lines.map((line) => { 528 return targetCell + "-" + line; 529 }) 530 let top = null; 531 let height = null; 532 let parent = null; 533 if (lineIds.length > 0) { 534 //compute the position of the single el (top and bottom and make a div) 535 const el = window.document.getElementById(lineIds[0]); 536 top = el.offsetTop; 537 height = el.offsetHeight; 538 parent = el.parentElement.parentElement; 539 if (lineIds.length > 1) { 540 const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]); 541 const bottom = lastEl.offsetTop + lastEl.offsetHeight; 542 height = bottom - top; 543 } 544 if (top !== null && height !== null && parent !== null) { 545 // cook up a div (if necessary) and position it 546 let div = window.document.getElementById("code-annotation-line-highlight"); 547 if (div === null) { 548 div = window.document.createElement("div"); 549 div.setAttribute("id", "code-annotation-line-highlight"); 550 div.style.position = 'absolute'; 551 parent.appendChild(div); 552 } 553 div.style.top = top - 2 + "px"; 554 div.style.height = height + 4 + "px"; 555 div.style.left = 0; 556 let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter"); 557 if (gutterDiv === null) { 558 gutterDiv = window.document.createElement("div"); 559 gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter"); 560 gutterDiv.style.position = 'absolute'; 561 const codeCell = window.document.getElementById(targetCell); 562 const gutter = codeCell.querySelector('.code-annotation-gutter'); 563 gutter.appendChild(gutterDiv); 564 } 565 gutterDiv.style.top = top - 2 + "px"; 566 gutterDiv.style.height = height + 4 + "px"; 567 } 568 selectedAnnoteEl = annoteEl; 569 } 570 }; 571 const unselectCodeLines = () => { 572 const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"]; 573 elementsIds.forEach((elId) => { 574 const div = window.document.getElementById(elId); 575 if (div) { 576 div.remove(); 577 } 578 }); 579 selectedAnnoteEl = undefined; 580 }; 581 // Handle positioning of the toggle 582 window.addEventListener( 583 "resize", 584 throttle(() => { 585 elRect = undefined; 586 if (selectedAnnoteEl) { 587 selectCodeLines(selectedAnnoteEl); 588 } 589 }, 10) 590 ); 591 function throttle(fn, ms) { 592 let throttle = false;
593 let timer; 594 return (...args) => { 595 if(!throttle) { // first call gets through 596 fn.apply(this, args); 597 throttle = true; 598 } else { // all the others get throttled 599 if(timer) clearTimeout(timer); // cancel #2 600 timer = setTimeout(() => { 601 fn.apply(this, args); 602 timer = throttle = false; 603 }, ms); 604 } 605 }; 606 } 607 // Attach click handler to the DT 608 const annoteDls = window.document.querySelectorAll('dt[data-target-cell]'); 609 for (const annoteDlNode of annoteDls) { 610 annoteDlNode.addEventListener('click', (event) => { 611 const clickedEl = event.target; 612 if (clickedEl !== selectedAnnoteEl) { 613 unselectCodeLines(); 614 const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active'); 615 if (activeEl) { 616 activeEl.classList.remove('code-annotation-active'); 617 } 618 selectCodeLines(clickedEl); 619 clickedEl.classList.add('code-annotation-active'); 620 } else { 621 // Unselect the line 622 unselectCodeLines(); 623 clickedEl.classList.remove('code-annotation-active'); 624 } 625 }); 626 } 627 const findCites = (el) => { 628 const parentEl = el.parentElement; 629 if (parentEl) { 630 const cites = parentEl.dataset.cites; 631 if (cites) { 632 return { 633 el, 634 cites: cites.split(' ') 635 }; 636 } else { 637 return findCites(el.parentElement) 638 } 639 } else { 640 return undefined; 641 } 642 }; 643 var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]'); 644 for (var i=0; i<bibliorefs.length; i++) { 645 const ref = bibliorefs[i]; 646 const citeInfo = findCites(ref); 647 if (citeInfo) { 648 tippyHover(citeInfo.el, function() { 649 var popup = window.document.createElement('div'); 650 citeInfo.cites.forEach(function(cite) { 651 var citeDiv = window.document.createElement('div'); 652 citeDiv.classList.add('hanging-indent'); 653 citeDiv.classList.add('csl-entry'); 654 var biblioDiv = window.document.getElementById('ref-' + cite); 655 if (biblioDiv) { 656 citeDiv.innerHTML = biblioDiv.innerHTML; 657 } 658 popup.appendChild(citeDiv); 659 }); 660 return popup.innerHTML; 661 }); 662 } 663 } 664 }); 665 </script>
665 666</div> <!-- /content --> 667<footer class="footer"> 668 <div class="nav-footer"> 669 <div class="nav-footer-left"> 670 671 </div> 672 <div class="nav-footer-center"> 673 <ul class="footer-items list-unstyled"> 674 <li class="nav-item"> 675 Contact: <a href="mailto:[email protected]">[email protected]</a><br> 676<a href="https://www.linkedin.com/company/fews-lab" target="_blank"><i class="bi bi-linkedin"></i> FEWsLab</a> 677<a href="https://www.linkedin.com/in/caitlinagrady/" target="_blank"><i class="bi bi-linkedin"></i> Caitlin Grady</a> 678<a href="https://bsky.app/profile/caitlinagrady.bsky.social" target="_blank"><i class="fa fa-brands fa-bluesky"></i> Bluesky</a><br> 679Site made with <a href="https://quarto.org/" target="_blank"><img src="https://quarto.org/favicon.png" width="12"> Quarto</a><br> 680© 2025 FEWsLab 681 </li> 682</ul> 683 </div> 684 <div class="nav-footer-right"> 685 686 </div> 687 </div> 688</footer> 689 690 691 692
693<script src="site_libs/quarto-html/zenscroll-min.js"></script>
693 694</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.