PageSourceSearch

https://mavrxlab.org/about/

html mavrxlab.org collected 2026-10-06 13:17:24 UTC 30,238 bytes, 706 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.6.40">
6
7<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
8
9
10<title>Lab Safety, Policies, and FAQ – MA{VR}X Lab</title>
11<style>
12code{white-space: pre-wrap;}
13span.smallcaps{font-variant: small-caps;}
14div.columns{display: flex; gap: min(4vw, 1.5em);}
15div.column{flex: auto; overflow-x: auto;}
16div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
17ul.task-list{list-style: none;}
18ul.task-list li input[type="checkbox"] {
19  width: 0.8em;
20  margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */ 
21  vertical-align: middle;
22}
23</style>
24
25
26<script src="../site_libs/quarto-nav/quarto-nav.js"></script>
vendor: 1 bytes, line 26
26
27<script src="../site_libs/quarto-nav/headroom.min.js"></script>
vendor: 1 bytes, line 27
27
28<script src="../site_libs/clipboard/clipboard.min.js"></script>
vendor: 1 bytes, line 28
28
29<script src="../site_libs/quarto-search/autocomplete.umd.js"></script>
vendor: 1 bytes, line 29
29
30<script src="../site_libs/quarto-search/fuse.min.js"></script>
vendor: 1 bytes, line 30
30
31<script src="../site_libs/quarto-search/quarto-search.js"></script>
31
32<meta name="quarto:offset" content="../">
33<script src="../site_libs/quarto-html/quarto.js"></script>
vendor: 1 bytes, line 33
33
34<script src="../site_libs/quarto-html/popper.min.js"></script>
vendor: 1 bytes, line 34
34
35<script src="../site_libs/quarto-html/tippy.umd.min.js"></script>
vendor: 1 bytes, line 35
35
36<script src="../site_libs/quarto-html/anchor.min.js"></script>
36
37<link href="../site_libs/quarto-html/tippy.css" rel="stylesheet">
38<link href="../site_libs/quarto-html/quarto-syntax-highlighting-549806ee2085284f45b00abea8c6df48.css" rel="stylesheet" id="quarto-text-highlighting-styles">
39<script src="../site_libs/bootstrap/bootstrap.min.js"></script>
39
40<link href="../site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
41<link href="../site_libs/bootstrap/bootstrap-d83fba8907f73068b64e07941be842b2.min.css" rel="stylesheet" append-hash="true" id="quarto-bootstrap" data-mode="light">
42<link href="../site_libs/quarto-contrib/fontawesome6-0.1.0/all.css" rel="stylesheet">
43<link href="../site_libs/quarto-contrib/fontawesome6-0.1.0/latex-fontsize.css" rel="stylesheet">
44<script id="quarto-search-options" type="application/json">{
45  "location": "navbar",
46  "copy-button": false,
47  "collapse-after": 3,
48  "panel-placement": "end",
49  "type": "overlay",
50  "limit": 50,
51  "keyboard-shortcut": [
52    "f",
53    "/",
54    "s"
55  ],
56  "show-item-context": false,
57  "language": {
58    "search-no-results-text": "No results",
59    "search-matching-documents-text": "matching documents",
60    "search-copy-link-title": "Copy link to search",
61    "search-hide-matches-text": "Hide additional matches",
62    "search-more-match-text": "more match in this document",
63    "search-more-matches-text": "more matches in this document",
64    "search-clear-button-title": "Clear",
65    "search-text-placeholder": "",
66    "search-detached-cancel-button-title": "Cancel",
67    "search-submit-button-title": "Submit",
68    "search-label": "Search"
69  }
70}</script>
70
71<!-- Proxima Nova reference. -->
72<link href="https://use.typekit.net/emv3zbo.css" rel="stylesheet" crossorigin="anonymous">
73<!-- Arizona Bootstrap reference. -->
74<link rel="stylesheet" href="https://cdn.digital.arizona.edu/lib/arizona-bootstrap/2.0.19/css/arizona-bootstrap.min.css" crossorigin="anonymous">
75<script src="../site_libs/htmlwidgets-1.5.4/htmlwidgets.js"></script>
vendor: 1 bytes, line 75
75
76<script src="../site_libs/pymjs-1.3.2/pym.v1.js"></script>
vendor: 1 bytes, line 76
76
77<script src="../site_libs/widgetframe-binding-0.3.1/widgetframe.js"></script>
77
78
79
80<link rel="stylesheet" href="../styles.css">
81<meta property="og:title" content="Lab Safety, Policies, and FAQ – MA{VR}X Lab">
82<meta property="og:description" content="Official site for the University of Arizona’s MA{VR}X Lab">
83<meta property="og:image" content="https://mavrxlab.org/about/CX2.png">
84<meta property="og:site_name" content="MA{VR}X Lab">
85<meta property="og:image:height" content="336">
86<meta property="og:image:width" content="418">
87</head>
88
89<body class="nav-fixed">
90
91<div id="quarto-search-results"></div>
92  <header id="quarto-header" class="headroom fixed-top quarto-banner">
93    <nav class="navbar navbar-expand-lg " data-bs-theme="dark">
94      <div class="navbar-container container-fluid">
95      <div class="navbar-brand-container mx-auto">
96    <a class='navbar-brand navbar-brand-logo' href='/'>
97    <img src="../assets/images/big-banner-white.png" alt="MA{VR}X Lab" class="navbar-logo">
98    </a>
99  </div>
100            <div id="quarto-search" class="" title="Search"></div>
101          <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(); }">
102  <span class="navbar-toggler-icon"></span>
103</button>
104          <div class="collapse navbar-collapse" id="navbarCollapse">
105            <ul class="navbar-nav navbar-nav-scroll me-auto">
106  <li class="nav-item">
107    <a class='nav-link' href='/'> 
108<span class="menu-text">Home</span></a>
109  </li>  
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='/news'> 
116<span class="menu-text">News</span></a>
117  </li>  
118  <li class="nav-item">
119    <a class='nav-link' href='/projects'> 
120<span class="menu-text">Projects</span></a>
121  </li>  
122  <li class="nav-item">
123    <a class="nav-link" href="../team/"> 
124<span class="menu-text">Team</span></a>
125  </li>  
126  <li class="nav-item">
127    <a class="nav-link" href="../resources/"> 
128<span class="menu-text">Resources</span></a>
129  </li>  
130</ul>
131            <ul class="navbar-nav navbar-nav-scroll ms-auto">
132  <li class="nav-item compact">
133    <a class="nav-link" href="../index.xml"> <i class="bi bi-rss" role="img">
134</i> 
135<span class="menu-text"></span></a>
136  </li>  
137</ul>
138          </div> <!-- /navcollapse -->
139            <div class="quarto-navbar-tools">
140</div>
141      </div> <!-- /container-fluid -->
142    </nav>
143</header>
144<!-- content -->
145<header id="title-block-header" class="quarto-title-block default page-columns page-full">
146  <div class="quarto-title-banner page-columns page-full">
147    <div class="quarto-title column-body">
148      <h1 class="title">Lab Safety, Policies, and FAQ</h1>
149                      </div>
150  </div>
151    
152  
153  <div class="quarto-title-meta">
154
155      
156    
157      
158    </div>
159    
160  
161  </header><div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
162<!-- sidebar -->
163<!-- margin-sidebar -->
164    <div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
165        <nav id="TOC" role="doc-toc" class="toc-active">
166    <h2 id="toc-title">On this page</h2>
167   
168  <ul>
169  <li><a href="#lab-safety" id="toc-lab-safety" class="nav-link active" data-scroll-target="#lab-safety">Lab Safety</a></li>
170  <li><a href="#policies" id="toc-policies" class="nav-link" data-scroll-target="#policies">Policies</a>
171  <ul class="collapse">
172  <li><a href="#lab-rules" id="toc-lab-rules" class="nav-link" data-scroll-target="#lab-rules">Lab Rules</a></li>
173  <li><a href="#safety-disclaimer" id="toc-safety-disclaimer" class="nav-link" data-scroll-target="#safety-disclaimer">Safety Disclaimer</a></li>
174  </ul></li>
175  <li><a href="#faq" id="toc-faq" class="nav-link" data-scroll-target="#faq">FAQ</a>
176  <ul class="collapse">
177  <li><a href="#where-is-the-mavrx-lab" id="toc-where-is-the-mavrx-lab" class="nav-link" data-scroll-target="#where-is-the-mavrx-lab">Where is the MA{VR}X Lab?</a></li>
178  <li><a href="#what-are-the-labs-hours-of-operation" id="toc-what-are-the-labs-hours-of-operation" class="nav-link" data-scroll-target="#what-are-the-labs-hours-of-operation">What are the lab’s hours of operation?</a></li>
179  <li><a href="#what-equipment-does-the-lab-have" id="toc-what-equipment-does-the-lab-have" class="nav-link" data-scroll-target="#what-equipment-does-the-lab-have">What equipment does the lab have?</a></li>
180  </ul></li>
181  </ul>
182</nav>
183    </div>
184<!-- main -->
185<main class="content quarto-banner-title-block" id="quarto-document-content">
186
187
188
189
190
191<section id="lab-safety" class="level2">
192<h2 class="anchored" data-anchor-id="lab-safety">Lab Safety</h2>
193<p>The MA{VR}X Lab should be a fun, educational, and inspiring experience for everyone. Here’s how we make sure that happens.</p>
194<p>We are taking the following precautions to prioritize the health of everyone involved, both lab staff and participants:</p>
195<p><strong>Please note: appointments are required for all in-person MA{VR}X Lab activities, events, and experiences unless otherwise specified!</strong></p>
196<p>Due to COVID-19, the MA{VR}X Lab–while encouraging participation and free use–is open only by appointment and for a limited number of simultaneous users. Contact <code>[email protected]</code> to schedule time or equipment rental.</p>
197<p>The lab is large enough that social distancing can be maintained to the degree required by the university. However, <strong>masks are required at all times in the lab</strong> when social distancing cannot be observed. Those using headsets will be provided disposable mask guards to use and equipment is sanitized in a <a href="https://cleanboxtech.com/cx-series">UV-C Cleanbox CX2</a> between uses.</p>
198<div class="quarto-figure quarto-figure-center">
199<figure class="figure">
200<p><img src="CX2.png" class="img-fluid figure-img"></p>
201<figcaption>The CX2</figcaption>
202</figure>
203</div>
204</section>
205<section id="policies" class="level2">
206<h2 class="anchored" data-anchor-id="policies">Policies</h2>
207<p>To ensure safe and equitable use of the lab, the following policies and disclaimers must be acknowledged and followed.</p>
208<section id="lab-rules" class="level3">
209<h3 class="anchored" data-anchor-id="lab-rules">Lab Rules</h3>
210<p>The following rules apply to the lab, <em>both physically and virtually</em>.</p>
211<ul>
212<li>General use of the MA{VR}X Lab is available free of charge for all University of Arizona community members.</li>
213<li>All equipment usage <em>must</em> be scheduled and booked ahead of time. Walk-ins, while permitted, do not take priority over scheduled events or activities.</li>
214<li>Ask the lab staff if you wish to move any tables, equipment, cables, and so on.</li>
215<li>No food or open drink containers allowed in the lab.</li>
216<li>Copyright infringement is prohibited.</li>
217<li>Bringing your own equipment is permitted and encouraged.</li>
218<li>Any software installed on lab equipment requires staff approval.</li>
219<li>All <a href="https://deanofstudents.arizona.edu/student-rights-responsibilities/student-code-conduct">University of Arizona Code of Conduct</a> policies also apply within the lab.</li>
220</ul>
221</section>
222<section id="safety-disclaimer" class="level3">
223<h3 class="anchored" data-anchor-id="safety-disclaimer">Safety Disclaimer</h3>
224<p>All participants involved in MA{VR}X Lab activities are required to acknowledge the following safety disclaimer.</p>
225<blockquote class="blockquote">
226<p>Please be aware that using a virtual reality headset (such as the HTC Vive or Oculus Rift) may cause dizziness, headaches, disorientation, and seizures. Individuals who are prone to motion sickness may experience discomfort when using a virtual reality headset, as some experiences involve varying degrees of movement and motion.</p>
227<p>Should you experience any of the above symptoms or begin to feel uncomfortable with completing a virtual reality experience, remove the headset immediately and one of the lab or other staff members will assist you.</p>
228<p>Due to the immersive nature of virtual reality, it is also possible to lose awareness of your surroundings while engaged in an experience. Because of this, when wearing the headset please be cautious of other people, equipment, and/or miscellaneous items that may be within your immediate surroundings to avoid any unnecessary bodily injuries or damage to equipment.</p>
229</blockquote>
230</section>
231</section>
232<section id="faq" class="level2">
233<h2 class="anchored" data-anchor-id="faq">FAQ</h2>
234<section id="where-is-the-mavrx-lab" class="level3">
235<h3 class="anchored" data-anchor-id="where-is-the-mavrx-lab">Where is the MA{VR}X Lab?</h3>
236<p>Two places! The primary lab is located in the College of Applied Science and Technology on the University of Arizona Sierra Vista campus.</p>
237<div class="cell">
238<div class="cell-output-display">
239<div id="htmlwidget-774b51d34f56493d3021" style="width:100%;height:400px;" class="widgetframe html-widget"></div>
240<script type="application/json" data-for="htmlwidget-774b51d34f56493d3021">{"x":{"url":"index_files/figure-html//widgets/widget_svmap.html","options":{"xdomain":"*","allowfullscreen":false,"lazyload":false}},"evals":[],"jsHooks":[]}</script>
240
241</div>
242</div>
243<p>You can also find a satellite lab on the Yuma campus.</p>
244</section>
245<section id="what-are-the-labs-hours-of-operation" class="level3">
246<h3 class="anchored" data-anchor-id="what-are-the-labs-hours-of-operation">What are the lab’s hours of operation?</h3>
247<p>Due to the varying projects ongoing that the lab is involved in, time is available <strong>only</strong> via appointment. Please contact <code>[email protected]</code> to schedule time to work in the lab or book equipment.</p>
248</section>
249<section id="what-equipment-does-the-lab-have" class="level3">
250<h3 class="anchored" data-anchor-id="what-equipment-does-the-lab-have">What equipment does the lab have?</h3>
251<p>You can see a running list of the available hardware, software, and games on the <a href="../resources/">Lab Resources</a> page.</p>
252
253
254</section>
255</section>
256
257</main> <!-- /main -->
258<script id="quarto-html-after-body" type="application/javascript">
259window.document.addEventListener("DOMContentLoaded", function (event) {
260  const toggleBodyColorMode = (bsSheetEl) => {
261    const mode = bsSheetEl.getAttribute("data-mode");
262    const bodyEl = window.document.querySelector("body");
263    if (mode === "dark") {
264      bodyEl.classList.add("quarto-dark");
265      bodyEl.classList.remove("quarto-light");
266    } else {
267      bodyEl.classList.add("quarto-light");
268      bodyEl.classList.remove("quarto-dark");
269    }
270  }
271  const toggleBodyColorPrimary = () => {
272    const bsSheetEl = window.document.querySelector("link#quarto-bootstrap");
273    if (bsSheetEl) {
274      toggleBodyColorMode(bsSheetEl);
275    }
276  }
277  toggleBodyColorPrimary();  
278  const icon = "";
279  const anchorJS = new window.AnchorJS();
280  anchorJS.options = {
281    placement: 'right',
282    icon: icon
283  };
284  anchorJS.add('.anchored');
285  const isCodeAnnotation = (el) => {
286    for (const clz of el.classList) {
287      if (clz.startsWith('code-annotation-')) {                     
288        return true;
289      }
290    }
291    return false;
292  }
293  const onCopySuccess = function(e) {
294    // button target
295    const button = e.trigger;
296    // don't keep focus
297    button.blur();
298    // flash "checked"
299    button.classList.add('code-copy-button-checked');
300    var currentTitle = button.getAttribute("title");
301    button.setAttribute("title", "Copied!");
302    let tooltip;
303    if (window.bootstrap) {
304      button.setAttribute("data-bs-toggle", "tooltip");
305      button.setAttribute("data-bs-placement", "left");
306      button.setAttribute("data-bs-title", "Copied!");
307      tooltip = new bootstrap.Tooltip(button, 
308        { trigger: "manual", 
309          customClass: "code-copy-button-tooltip",
310          offset: [0, -8]});
311      tooltip.show();    
312    }
313    setTimeout(function() {
314      if (tooltip) {
315        tooltip.hide();
316        button.removeAttribute("data-bs-title");
317        button.removeAttribute("data-bs-toggle");
318        button.removeAttribute("data-bs-placement");
319      }
320      button.setAttribute("title", currentTitle);
321      button.classList.remove('code-copy-button-checked');
322    }, 1000);
323    // clear code selection
324    e.clearSelection();
325  }
326  const getTextToCopy = function(trigger) {
327      const codeEl = trigger.previousElementSibling.cloneNode(true);
328      for (const childEl of codeEl.children) {
329        if (isCodeAnnotation(childEl)) {
330          childEl.remove();
331        }
332      }
333      return codeEl.innerText;
334  }
335  const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', {
336    text: getTextToCopy
337  });
338  clipboard.on('success', onCopySuccess);
339  if (window.document.getElementById('quarto-embedded-source-code-modal')) {
340    const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', {
341      text: getTextToCopy,
342      container: window.document.getElementById('quarto-embedded-source-code-modal')
343    });
344    clipboardModal.on('success', onCopySuccess);
345  }
346    var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//);
347    var mailtoRegex = new RegExp(/^mailto:/);
348      var filterRegex = new RegExp("https:\/\/mavrxlab\.org");
349    var isInternal = (href) => {
350        return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href);
351    }
352    // Inspect non-navigation links and adorn them if external
353 	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)');
354    for (var i=0; i<links.length; i++) {
355      const link = links[i];
356      if (!isInternal(link.href)) {
357        // undo the damage that might have been done by quarto-nav.js in the case of
358        // links that we want to consider external
359        if (link.dataset.originalHref !== undefined) {
360          link.href = link.dataset.originalHref;
361        }
362      }
363    }
364  function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
365    const config = {
366      allowHTML: true,
367      maxWidth: 500,
368      delay: 100,
369      arrow: false,
370      appendTo: function(el) {
371          return el.parentElement;
372      },
373      interactive: true,
374      interactiveBorder: 10,
375      theme: 'quarto',
376      placement: 'bottom-start',
377    };
378    if (contentFn) {
379      config.content = contentFn;
380    }
381    if (onTriggerFn) {
382      config.onTrigger = onTriggerFn;
383    }
384    if (onUntriggerFn) {
385      config.onUntrigger = onUntriggerFn;
386    }
387    window.tippy(el, config); 
388  }
389  const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
390  for (var i=0; i<noterefs.length; i++) {
391    const ref = noterefs[i];
392    tippyHover(ref, function() {
393      // use id or data attribute instead here
394      let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
395      try { href = new URL(href).hash; } catch {}
396      const id = href.replace(/^#\/?/, "");
397      const note = window.document.getElementById(id);
398      if (note) {
399        return note.innerHTML;
400      } else {
401        return "";
402      }
403    });
404  }
405  const xrefs = window.document.querySelectorAll('a.quarto-xref');
406  const processXRef = (id, note) => {
407    // Strip column container classes
408    const stripColumnClz = (el) => {
409      el.classList.remove("page-full", "page-columns");
410      if (el.children) {
411        for (const child of el.children) {
412          stripColumnClz(child);
413        }
414      }
415    }
416    stripColumnClz(note)
417    if (id === null || id.startsWith('sec-')) {
418      // Special case sections, only their first couple elements
419      const container = document.createElement("div");
420      if (note.children && note.children.length > 2) {
421        container.appendChild(note.children[0].cloneNode(true));
422        for (let i = 1; i < note.children.length; i++) {
423          const child = note.children[i];
424          if (child.tagName === "P" && child.innerText === "") {
425            continue;
426          } else {
427            container.appendChild(child.cloneNode(true));
428            break;
429          }
430        }
431        if (window.Quarto?.typesetMath) {
432          window.Quarto.typesetMath(container);
433        }
434        return container.innerHTML
435      } else {
436        if (window.Quarto?.typesetMath) {
437          window.Quarto.typesetMath(note);
438        }
439        return note.innerHTML;
440      }
441    } else {
442      // Remove any anchor links if they are present
443      const anchorLink = note.querySelector('a.anchorjs-link');
444      if (anchorLink) {
445        anchorLink.remove();
446      }
447      if (window.Quarto?.typesetMath) {
448        window.Quarto.typesetMath(note);
449      }
450      if (note.classList.contains("callout")) {
451        return note.outerHTML;
452      } else {
453        return note.innerHTML;
454      }
455    }
456  }
457  for (var i=0; i<xrefs.length; i++) {
458    const xref = xrefs[i];
459    tippyHover(xref, undefined, function(instance) {
460      instance.disable();
461      let url = xref.getAttribute('href');
462      let hash = undefined; 
463      if (url.startsWith('#')) {
464        hash = url;
465      } else {
466        try { hash = new URL(url).hash; } catch {}
467      }
468      if (hash) {
469        const id = hash.replace(/^#\/?/, "");
470        const note = window.document.getElementById(id);
471        if (note !== null) {
472          try {
473            const html = processXRef(id, note.cloneNode(true));
474            instance.setContent(html);
475          } finally {
476            instance.enable();
477            instance.show();
478          }
479        } else {
480          // See if we can fetch this
481          fetch(url.split('#')[0])
482          .then(res => res.text())
483          .then(html => {
484            const parser = new DOMParser();
485            const htmlDoc = parser.parseFromString(html, "text/html");
486            const note = htmlDoc.getElementById(id);
487            if (note !== null) {
488              const html = processXRef(id, note);
489              instance.setContent(html);
490            } 
491          }).finally(() => {
492            instance.enable();
493            instance.show();
494          });
495        }
496      } else {
497        // See if we can fetch a full url (with no hash to target)
498        // This is a special case and we should probably do some content thinning / targeting
499        fetch(url)
500        .then(res => res.text())
501        .then(html => {
502          const parser = new DOMParser();
503          const htmlDoc = parser.parseFromString(html, "text/html");
504          const note = htmlDoc.querySelector('main.content');
505          if (note !== null) {
506            // This should only happen for chapter cross references
507            // (since there is no id in the URL)
508            // remove the first header
509            if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
510              note.children[0].remove();
511            }
512            const html = processXRef(null, note);
513            instance.setContent(html);
514          } 
515        }).finally(() => {
516          instance.enable();
517          instance.show();
518        });
519      }
520    }, function(instance) {
521    });
522  }
523      let selectedAnnoteEl;
524      const selectorForAnnotation = ( cell, annotation) => {
525        let cellAttr = 'data-code-cell="' + cell + '"';
526        let lineAttr = 'data-code-annotation="' +  annotation + '"';
527        const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
528        return selector;
529      }
530      const selectCodeLines = (annoteEl) => {
531        const doc = window.document;
532        const targetCell = annoteEl.getAttribute("data-target-cell");
533        const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
534        const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
535        const lines = annoteSpan.getAttribute("data-code-lines").split(",");
536        const lineIds = lines.map((line) => {
537          return targetCell + "-" + line;
538        })
539        let top = null;
540        let height = null;
541        let parent = null;
542        if (lineIds.length > 0) {
543            //compute the position of the single el (top and bottom and make a div)
544            const el = window.document.getElementById(lineIds[0]);
545            top = el.offsetTop;
546            height = el.offsetHeight;
547            parent = el.parentElement.parentElement;
548          if (lineIds.length > 1) {
549            const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
550            const bottom = lastEl.offsetTop + lastEl.offsetHeight;
551            height = bottom - top;
552          }
553          if (top !== null && height !== null && parent !== null) {
554            // cook up a div (if necessary) and position it 
555            let div = window.document.getElementById("code-annotation-line-highlight");
556            if (div === null) {
557              div = window.document.createElement("div");
558              div.setAttribute("id", "code-annotation-line-highlight");
559              div.style.position = 'absolute';
560              parent.appendChild(div);
561            }
562            div.style.top = top - 2 + "px";
563            div.style.height = height + 4 + "px";
564            div.style.left = 0;
565            let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
566            if (gutterDiv === null) {
567              gutterDiv = window.document.createElement("div");
568              gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
569              gutterDiv.style.position = 'absolute';
570              const codeCell = window.document.getElementById(targetCell);
571              const gutter = codeCell.querySelector('.code-annotation-gutter');
572              gutter.appendChild(gutterDiv);
573            }
574            gutterDiv.style.top = top - 2 + "px";
575            gutterDiv.style.height = height + 4 + "px";
576          }
577          selectedAnnoteEl = annoteEl;
578        }
579      };
580      const unselectCodeLines = () => {
581        const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
582        elementsIds.forEach((elId) => {
583          const div = window.document.getElementById(elId);
584          if (div) {
585            div.remove();
586          }
587        });
588        selectedAnnoteEl = undefined;
589      };
590        // Handle positioning of the toggle
591    window.addEventListener(
592      "resize",
593      throttle(() => {
594        elRect = undefined;
595        if (selectedAnnoteEl) {
596          selectCodeLines(selectedAnnoteEl);
597        }
598      }, 10)
599    );
600    function throttle(fn, ms) {
601    let throttle = false;
602    let timer;
603      return (...args) => {
604        if(!throttle) { // first call gets through
605            fn.apply(this, args);
606            throttle = true;
607        } else { // all the others get throttled
608            if(timer) clearTimeout(timer); // cancel #2
609            timer = setTimeout(() => {
610              fn.apply(this, args);
611              timer = throttle = false;
612            }, ms);
613        }
614      };
615    }
616      // Attach click handler to the DT
617      const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
618      for (const annoteDlNode of annoteDls) {
619        annoteDlNode.addEventListener('click', (event) => {
620          const clickedEl = event.target;
621          if (clickedEl !== selectedAnnoteEl) {
622            unselectCodeLines();
623            const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
624            if (activeEl) {
625              activeEl.classList.remove('code-annotation-active');
626            }
627            selectCodeLines(clickedEl);
628            clickedEl.classList.add('code-annotation-active');
629          } else {
630            // Unselect the line
631            unselectCodeLines();
632            clickedEl.classList.remove('code-annotation-active');
633          }
634        });
635      }
636  const findCites = (el) => {
637    const parentEl = el.parentElement;
638    if (parentEl) {
639      const cites = parentEl.dataset.cites;
640      if (cites) {
641        return {
642          el,
643          cites: cites.split(' ')
644        };
645      } else {
646        return findCites(el.parentElement)
647      }
648    } else {
649      return undefined;
650    }
651  };
652  var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
653  for (var i=0; i<bibliorefs.length; i++) {
654    const ref = bibliorefs[i];
655    const citeInfo = findCites(ref);
656    if (citeInfo) {
657      tippyHover(citeInfo.el, function() {
658        var popup = window.document.createElement('div');
659        citeInfo.cites.forEach(function(cite) {
660          var citeDiv = window.document.createElement('div');
661          citeDiv.classList.add('hanging-indent');
662          citeDiv.classList.add('csl-entry');
663          var biblioDiv = window.document.getElementById('ref-' + cite);
664          if (biblioDiv) {
665            citeDiv.innerHTML = biblioDiv.innerHTML;
666          }
667          popup.appendChild(citeDiv);
668        });
669        return popup.innerHTML;
670      });
671    }
672  }
673});
674</script>
674
675</div> <!-- /content -->
676<footer class="footer">
677  <div class="nav-footer">
678    <div class="nav-footer-left">
679<p><i class="fa-regular fa-copyright" aria-label="copyright"></i> Ryan Straight, 2024<br> All content licensed under <i class="fa-brands fa-creative-commons" aria-label="creative-commons"></i> <i class="fa-brands fa-creative-commons-by" aria-label="creative-commons-by"></i> <i class="fa-brands fa-creative-commons-sa" aria-label="creative-commons-sa"></i> <i class="fa-brands fa-creative-commons-nc" aria-label="creative-commons-nc"></i> <a href="http://creativecommons.org/licenses/by-nc-sa/4.0/">(CC BY-NC-SA 4.0)</a></p>
680</div>   
681    <div class="nav-footer-center">
682      <ul class="footer-items list-unstyled">
683    <li class="nav-item compact">
684    <a class="nav-link" href="https://github.com/mavrxlab/">
685      <i class="bi bi-github" role="img" aria-label="GitHub">
686</i> 
687    </a>
688  </li>  
689    <li class="nav-item compact">
690    <a class="nav-link" href="https://hci.social/@mavrxlab/">
691      <i class="bi bi-mastodon" role="img" aria-label="Mastodon">
692</i> 
693    </a>
694  </li>  
695</ul>
696    </div>
697    <div class="nav-footer-right">
698<p>Made with <i class="fa-brands fa-r-project" aria-label="r-project"></i> and <a href="https://quarto.org/">Quarto</a><br> with much inspiration from <a href="https://github.com/andreashandel/andreashandelwebsite">Andreas Handel</a>.</p>
699</div>
700  </div>
701</footer>
702
703
704
705
706</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.