PageSourceSearch

https://chrisvoncsefalvay.com/about/

html chrisvoncsefalvay.com collected 2026-09-24 09:28:34 UTC 38,535 bytes, 699 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.10.18">
6
7<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
8
9<meta name="description" content="Chris von Csefalvay is an AI researcher and computational epidemiologist. He leads post-training research and clinical intelligence at HCLTech.">
10
11<title>About – Chris von Csefalvay</title>
12<style>
13/* Default styles provided by pandoc.
14** See https://pandoc.org/MANUAL.html#variables-for-html for config info.
15*/
16span.smallcaps{font-variant: small-caps;}
17div.columns{display: flex; gap: 1.5em;}
18div.column{flex: auto;}
19@media screen {
20div.columns{gap: min(4vw, 1.5em);}
21div.column{overflow-x: auto;}
22}
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<script src="../site_libs/quarto-html/quarto.js" type="module"></script>
vendor: 1 bytes, line 40
40
41<script src="../site_libs/quarto-html/tabsets/tabsets.js" type="module"></script>
vendor: 1 bytes, line 41
41
42<script src="../site_libs/quarto-html/popper.min.js"></script>
vendor: 1 bytes, line 42
42
43<script src="../site_libs/quarto-html/tippy.umd.min.js"></script>
vendor: 1 bytes, line 43
43
44<script src="../site_libs/quarto-html/anchor.min.js"></script>
44
45<link href="../site_libs/quarto-html/tippy.css" rel="stylesheet">
46<link href="../site_libs/quarto-html/quarto-syntax-highlighting-64a204ab8560d761af7679ceaba22944.css" rel="stylesheet" id="quarto-text-highlighting-styles">
47<script src="../site_libs/bootstrap/bootstrap.min.js"></script>
47
48<link href="../site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
49<link href="../site_libs/bootstrap/bootstrap-55617497126496852ff9f5a59253c640.min.css" rel="stylesheet" append-hash="true" id="quarto-bootstrap" data-mode="light">
50<script id="quarto-search-options" type="application/json">{
51  "location": "navbar",
52  "copy-button": false,
53  "collapse-after": 3,
54  "panel-placement": "end",
55  "type": "overlay",
56  "limit": 50,
57  "keyboard-shortcut": [
58    "f",
59    "/",
60    "s"
61  ],
62  "show-item-context": false,
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<script async="" src="https://www.googletagmanager.com/gtag/js?id=395640625"></script>
76
77
78<script type="text/javascript">
79
80window.dataLayer = window.dataLayer || [];
81function gtag(){dataLayer.push(arguments);}
82gtag('js', new Date());
83gtag('config', '395640625', { 'anonymize_ip': true});
84</script>
84<script type="application/ld+json">{"@context":"https://schema.org","@type":"Person","@id":"https://chrisvoncsefalvay.com/#person","name":"Chris von Csefalvay","givenName":"Chris","familyName":"von Csefalvay","jobTitle":"Principal","description":"Chris von Csefalvay is a Principal at HCLTech's AI Practice, leading post-training research and clinical intelligence. He is an AI researcher and computational epidemiologist and the author of The Craft of Post-Training: A Practical Guide for AI Engineers and Developers (published by No Starch Press in 2026), Differentiable Photon Transport, Volume I: Foundations and Computational Modeling of Infectious Disease (Elsevier, 2023).","url":"https://chrisvoncsefalvay.com","image":"https://chrisvoncsefalvay.com/img/portrait_2x3midres.webp","sameAs":["https://orcid.org/0000-0003-3131-0864","https://scholar.google.com/citations?user=X_2G-VsAAAAJ","https://www.wikidata.org/wiki/Q107095298","https://hu.wikipedia.org/wiki/Chris_von_Csefalvay","https://github.com/chrisvoncsefalvay","https://twitter.com/epichrisis","https://www.linkedin.com/in/chrisvoncsefalvay/","https://www.instagram.com/chrisvoncsefalvay/","https://viaf.org/viaf/7190162669581955500004","https://isni.org/isni/0000000502655729","https://www.webofscience.com/wos/author/record/IZD-6900-2023","https://osf.io/awhgj","https://en.wikiquote.org/wiki/Chris_von_Csefalvay","https://www.researchgate.net/profile/Chris-Von-Csefalvay","https://www.crunchbase.com/person/chris-von-csefalvay","https://dblp.org/pid/157/8137.html","https://www.goodreads.com/author/show/15108248.Chris_von_Csefalvay","https://golden.com/wiki/Chris_von_Csefalvay-BY88G48","https://oxford.academia.edu/ChrisVonCsefalvay","https://medium.com/@chrisvcsefalvay","https://commons.wikimedia.org/wiki/Category:Chris_von_Csefalvay","https://sciprofiles.com/profile/1163482"],"address":{"@type":"PostalAddress","addressLocality":"Denver","addressRegion":"CO","addressCountry":"United States"},"alumniOf":[{"@type":"CollegeOrUniversity","name":"University of Oxford","sameAs":"https://en.wikipedia.org/wiki/University_of_Oxford"},{"@type":"CollegeOrUniversity","name":"Cardiff University","sameAs":"https://en.wikipedia.org/wiki/Cardiff_University"}],"worksFor":{"@type":"Organization","@id":"https://www.hcltech.com/#organization","name":"HCLTech","url":"https://www.hcltech.com","sameAs":"https://en.wikipedia.org/wiki/HCLTech"},"birthDate":"1986-07-15","birthPlace":{"@type":"Place","name":"Budapest","address":{"@type":"PostalAddress","addressCountry":"HU"}},"nationality":[{"@type":"Country","name":"United Kingdom"},{"@type":"Country","name":"Hungary"}],"memberOf":[{"@type":"Organization","name":"Royal Society for Public Health"},{"@type":"Organization","name":"IEEE"}],"knowsAbout":["post-training for language models","supervised fine-tuning","reinforcement learning from verifiable rewards","group relative policy optimization","agentic AI systems","multi-agent frameworks","large language models","LLM evaluation","computational epidemiology","AI alignment","LLMOps"],"hasCredential":[{"@type":"EducationalOccupationalCredential","name":"Certified in Public Health (CPH)","credentialCategory":"Professional Certification","recognizedBy":{"@type":"Organization","name":"National Board of Public Health Examiners","url":"https://www.nbphe.org"}},{"@type":"EducationalOccupationalCredential","name":"Fellow of the Royal Society for Public Health (FRSPH)","credentialCategory":"Fellowship","recognizedBy":{"@type":"Organization","name":"Royal Society for Public Health","url":"https://www.rsph.org.uk","sameAs":"https://en.wikipedia.org/wiki/Royal_Society_for_Public_Health"}},{"@type":"EducationalOccupationalCredential","name":"IEEE Senior Member","credentialCategory":"Professional Membership","recognizedBy":{"@type":"Organization","name":"IEEE","url":"https://www.ieee.org","sameAs":"https://en.wikipedia.org/wiki/Institute_of_Electrical_and_Electronics_Engineers"}}],"hasOccupation":{"@type":"Occupation","name":"AI Researcher and Computational Epidemiologist","occupationalCategory":"15-2051.00","skills":["Machine Learning","Natural Language Processing","Epidemiological Modeling","Reinforcement Learning","Large Language Models"]},"award":"Martin Wronker Prize, University of Oxford"}</script>
vendor: 1 bytes, line 84
84
85<script type="application/ld+json">{"@context":"https://schema.org","@type":"Book","@id":"https://chrisvoncsefalvay.com/#book-post-training","name":"The Craft of Post-Training","alternativeHeadline":"A Practical Guide for AI Engineers and Developers","isbn":"9781718505209","numberOfPages":416,"bookFormat":"https://schema.org/Paperback","inLanguage":"en","publisher":{"@type":"Organization","name":"No Starch Press"},"url":"https://posttraining.guide","sameAs":"https://www.amazon.com/dp/1718505205","datePublished":"2026","author":{"@id":"https://chrisvoncsefalvay.com/#person"}}</script>
vendor: 1 bytes, line 85
85
86<script type="application/ld+json">{"@context":"https://schema.org","@type":"Book","@id":"https://chrisvoncsefalvay.com/#book-cmid","name":"Computational Modeling of Infectious Disease","isbn":"9780323953894","inLanguage":"en","publisher":{"@type":"Organization","name":"Elsevier"},"url":"https://computationalinfectiousdisease.com","sameAs":"https://shop.elsevier.com/books/computational-modeling-of-infectious-disease/von-csefalvay/978-0-323-95389-4","datePublished":"2023-06-01","author":{"@id":"https://chrisvoncsefalvay.com/#person"}}</script>
vendor: 1 bytes, line 86
86
87<script type="application/ld+json">{"@context":"https://schema.org","@type":"Book","@id":"https://chrisvoncsefalvay.com/#book-photon-transport","name":"Differentiable Photon Transport","alternativeHeadline":"Volume I: Foundations","inLanguage":"en","url":"https://photontransport.com","datePublished":"2026","author":{"@id":"https://chrisvoncsefalvay.com/#person"}}</script>
vendor: 1 bytes, line 87
87
88<script type="application/ld+json">{"@context":"https://schema.org","@type":"WebSite","@id":"https://chrisvoncsefalvay.com/#website","name":"Chris von Csefalvay","url":"https://chrisvoncsefalvay.com","author":{"@id":"https://chrisvoncsefalvay.com/#person"},"description":"Chris von Csefalvay is an AI researcher and computational epidemiologist specialising in post-training for language models, agentic AI systems, and reinforcement learning from verifiable rewards.","inLanguage":"en"}</script>
88
89<meta name="author" content="Chris von Csefalvay">
90<link rel="me" href="https://github.com/chrisvoncsefalvay">
91<link rel="me" href="https://www.linkedin.com/in/chrisvoncsefalvay/">
92<link rel="me" href="https://orcid.org/0000-0003-3131-0864">
93<link rel="me" href="https://twitter.com/epichrisis">
94<link rel="me" href="https://www.wikidata.org/wiki/Q107095298">
95<link rel="me" href="https://scholar.google.com/citations?user=X_2G-VsAAAAJ">
95<script type="application/ld+json">{"@context":"https://schema.org","@type":"ProfilePage","@id":"https://chrisvoncsefalvay.com/about/#profile-page","url":"https://chrisvoncsefalvay.com/about/","name":"About Chris von Csefalvay","mainEntity":{"@type":"Person","@id":"https://chrisvoncsefalvay.com/#person","name":"Chris von Csefalvay"},"isPartOf":{"@id":"https://chrisvoncsefalvay.com/#website"}}</script>
95
96<link rel="canonical" href="https://chrisvoncsefalvay.com/about/">
97<meta property="og:url" content="https://chrisvoncsefalvay.com/about/">
98<meta property="og:type" content="website">
99
100
101<meta property="og:title" content="About – Chris von Csefalvay">
102<meta property="og:description" content="Chris von Csefalvay is an AI researcher and computational epidemiologist. He leads post-training research and clinical intelligence at HCLTech.">
103<meta property="og:image" content="https://chrisvoncsefalvay.com/img/portrait_2x3midres.webp">
104<meta property="og:site_name" content="Chris von Csefalvay">
105<meta name="twitter:title" content="About – Chris von Csefalvay">
106<meta name="twitter:description" content="Chris von Csefalvay is an AI researcher and computational epidemiologist. He leads post-training research and clinical intelligence at HCLTech.">
107<meta name="twitter:image" content="https://chrisvoncsefalvay.com/img/portrait_2x3midres.webp">
108<meta name="twitter:creator" content="@epichrisis">
109<meta name="twitter:site" content="@epichrisis">
110<meta name="twitter:card" content="summary_large_image">
111</head>
112
113<body class="nav-fixed quarto-light">
114
115<div id="quarto-search-results"></div>
116  <header id="quarto-header" class="headroom fixed-top">
117    <nav class="navbar navbar-expand-lg " data-bs-theme="dark">
118      <div class="navbar-container container-fluid">
119      <div class="navbar-brand-container mx-auto">
120    <a class="navbar-brand" href="../index.html">
121    <span class="navbar-title">Chris von Csefalvay</span>
122    </a>
123  </div>
124            <div id="quarto-search" class="" title="Search"></div>
125          <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(); }">
126  <span class="navbar-toggler-icon"></span>
127</button>
128          <div class="collapse navbar-collapse" id="navbarCollapse">
129            <ul class="navbar-nav navbar-nav-scroll me-auto">
130  <li class="nav-item">
131    <a class="nav-link" href="../index.html"> 
132<span class="menu-text">Home</span></a>
133  </li>  
134  <li class="nav-item">
135    <a class="nav-link" href="../about"> 
136<span class="menu-text">About</span></a>
137  </li>  
138  <li class="nav-item">
139    <a class="nav-link" href="../papers"> 
140<span class="menu-text">Papers</span></a>
141  </li>  
142  <li class="nav-item">
143    <a class="nav-link" href="../teaching"> 
144<span class="menu-text">Teaching</span></a>
145  </li>  
146  <li class="nav-item">
147    <a class="nav-link" href="../media"> 
148<span class="menu-text">Media</span></a>
149  </li>  
150  <li class="nav-item">
151    <a class="nav-link" href="../posts"> 
152<span class="menu-text">The Notebook</span></a>
153  </li>  
154  <li class="nav-item">
155    <a class="nav-link" href="../talks"> 
156<span class="menu-text">Talks</span></a>
157  </li>  
158  <li class="nav-item">
159    <a class="nav-link" href="https://computationalinfectiousdisease.com"> 
160<span class="menu-text">Computational Modeling of Infectious Disease</span></a>
161  </li>  
162  <li class="nav-item">
163    <a class="nav-link" href="https://nostarch.com/craft-of-post-training"> 
164<span class="menu-text">The Craft of Post-Training</span></a>
165  </li>  
166  <li class="nav-item">
167    <a class="nav-link" href="https://photontransport.com"> 
168<span class="menu-text">Differentiable Photon Transport</span></a>
169  </li>  
170</ul>
171          </div> <!-- /navcollapse -->
172            <div class="quarto-navbar-tools">
173</div>
174      </div> <!-- /container-fluid -->
175    </nav>
176</header>
177<!-- content -->
178<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
179<!-- sidebar -->
180<!-- margin-sidebar -->
181    <div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
182        <nav id="TOC" role="doc-toc" class="toc-active">
183    <h2 id="toc-title">On this page</h2>
184   
185  <ul>
186  <li><a href="#books" id="toc-books" class="nav-link active" data-scroll-target="#books">Books</a></li>
187  <li><a href="#research" id="toc-research" class="nav-link" data-scroll-target="#research">Research</a></li>
188  <li><a href="#education-and-credentials" id="toc-education-and-credentials" class="nav-link" data-scroll-target="#education-and-credentials">Education and credentials</a></li>
189  <li><a href="#professional-affiliations" id="toc-professional-affiliations" class="nav-link" data-scroll-target="#professional-affiliations">Professional affiliations</a></li>
190  <li><a href="#teaching-and-service" id="toc-teaching-and-service" class="nav-link" data-scroll-target="#teaching-and-service">Teaching and service</a></li>
191  <li><a href="#media-and-public-engagement" id="toc-media-and-public-engagement" class="nav-link" data-scroll-target="#media-and-public-engagement">Media and public engagement</a></li>
192  <li><a href="#personal" id="toc-personal" class="nav-link" data-scroll-target="#personal">Personal</a></li>
193  <li><a href="#contact" id="toc-contact" class="nav-link" data-scroll-target="#contact">Contact</a></li>
194  </ul>
195</nav>
196    </div>
197<!-- main -->
198<main class="content" id="quarto-document-content">
199
200<header id="title-block-header" class="quarto-title-block default">
201<div class="quarto-title">
202<h1 class="title">About</h1>
203</div>
204
205<div>
206  <div class="description">
207    Chris von Csefalvay is an AI researcher and computational epidemiologist. He leads post-training research and clinical intelligence at HCLTech.
208  </div>
209</div>
210
211
212<div class="quarto-title-meta">
213
214    
215  
216    
217  </div>
218  
219
220
221</header>
222
223
224<p>Chris von Csefalvay is an AI researcher and computational epidemiologist specialising in post-training for language models, agentic AI systems, and reinforcement learning from verifiable rewards (RLVR). He is a Principal at <a href="https://www.hcltech.com/">HCLTech</a>’s AI Practice, leading post-training research and clinical intelligence.</p>
225<section id="books" class="level2">
226<h2 class="anchored" data-anchor-id="books">Books</h2>
227<p>Chris is the author of three books:</p>
228<ul>
229<li><a href="https://nostarch.com/craft-of-post-training"><strong>The Craft of Post-Training: A Practical Guide for AI Engineers and Developers</strong></a> (No Starch Press, published 2026; now shipping on <a href="https://www.amazon.com/dp/1718505205">Amazon</a>) – a comprehensive guide to post-training techniques for large language models, including supervised fine-tuning, RLHF, DPO, and reinforcement learning from verifiable rewards.</li>
230<li><a href="https://photontransport.com"><strong>Differentiable Photon Transport, Volume I: Foundations</strong></a> – an illustrated, executable introduction to differentiable X-ray image formation, transport gradients and inverse imaging problems.</li>
231<li><a href="https://computationalinfectiousdisease.com"><strong>Computational Modeling of Infectious Disease</strong></a> (Elsevier, 2023) – a hands-on guide to computational epidemiology using Python, covering agent-based models, network epidemiology, and geospatial analysis.</li>
232</ul>
233</section>
234<section id="research" class="level2">
235<h2 class="anchored" data-anchor-id="research">Research</h2>
236<p>His research interests span post-training for language models, agentic AI systems, computational epidemiology, and public health informatics. He has published in peer-reviewed journals including <em>Acta Biomedica</em>, <em>Big Data and Cognitive Computing</em>, and <em>Frontiers in Medicine</em>, and his work has been cited in 39 English Wikipedia articles. He is a credited contributor to OEIS sequence <a href="https://oeis.org/A344856">A344856</a> (Jellyfish Heart numbers).</p>
237<p>His work also extends to physical AI and robotics simulation. With Tamás Földi, he is a principal investigator of the <a href="https://hcltech-robotics.github.io/asset-factory-blueprint/">Asset Factory Blueprint</a>, an open-source reference implementation from HCLTech’s Robotics Intelligence CoE for turning photographs, scans and CAD into reproducible OpenUSD assets and reinforcement learning environments.</p>
238</section>
239<section id="education-and-credentials" class="level2">
240<h2 class="anchored" data-anchor-id="education-and-credentials">Education and credentials</h2>
241<p>Chris attended the <a href="https://www.ox.ac.uk/">University of Oxford</a> (Merton College) for both his undergraduate and graduate studies, and holds degrees from <a href="https://www.cardiff.ac.uk/">Cardiff University</a> and Robert Gordon University Aberdeen, with further studies at the University of Leiden. He is <a href="https://cph.nbphe.org/employer_letter/19626">board certified in public health</a> (CPH), a Fellow of the <a href="https://www.rsph.org.uk/">Royal Society for Public Health</a> (FRSPH), and an IEEE Senior Member. He received the Martin Wronker Prize at the University of Oxford.</p>
242</section>
243<section id="professional-affiliations" class="level2">
244<h2 class="anchored" data-anchor-id="professional-affiliations">Professional affiliations</h2>
245<ul>
246<li><a href="https://ieee.org">IEEE</a> – Senior Member</li>
247<li><a href="https://www.rsph.org.uk/">Royal Society for Public Health</a> – Fellow</li>
248<li><a href="https://www.apha.org/">American Public Health Association</a> – Member</li>
249<li><a href="https://www.theorsociety.com/">The OR Society</a> – Member</li>
250<li><a href="https://www.topra.org/">TOPRA</a> – Registered Member</li>
251</ul>
252</section>
253<section id="teaching-and-service" class="level2">
254<h2 class="anchored" data-anchor-id="teaching-and-service">Teaching and service</h2>
255<p>Chris is a visiting thesis supervisor for students on the data science track of the mathematics programme at the <a href="https://www.bme.hu/?language=en">Budapest University of Technology and Economics</a>. He serves as a reviewer for <a href="https://joss.theoj.org/papers/reviewed_by/@chrisvoncsefalvay">JOSS</a>, <a href="https://loop.frontiersin.org/people/1398311/editorial">Frontiers in Immunology</a> and <a href="https://loop.frontiersin.org/people/1398311/editorial">Frontiers in Medicine</a>, and is a member of the Rocky Mountain MRC of Denver and Colorado’s radiation response MRC.</p>
256</section>
257<section id="media-and-public-engagement" class="level2">
258<h2 class="anchored" data-anchor-id="media-and-public-engagement">Media and public engagement</h2>
259<p>Chris’s work has been featured in the <a href="https://www.weforum.org/">World Economic Forum Technology Convergence Report 2025</a>, <a href="https://www.spectator.co.uk/writer/chris-von-csefalvay">The Spectator</a>, and <a href="https://www.city-journal.org/article/open-season">City Journal</a>. He has appeared on the <a href="https://www.techforgood.net/podcasts/series-two-chris-von-csefalvay">Tech For Good podcast</a> and other media outlets. He writes regularly on AI, post-training, and computational epidemiology on his <a href="https://chrisvoncsefalvay.com/posts/">blog</a>.</p>
260</section>
261<section id="personal" class="level2">
262<h2 class="anchored" data-anchor-id="personal">Personal</h2>
263<p>Born in Budapest, Hungary, Chris lives in Denver, Colorado. He is an adaptive multisport athlete, competing in wheelchair rugby, adaptive rowing (category PR1), and the SkiErg (category SIT2), where he holds multiple world records. He lives with <a href="https://en.wikipedia.org/wiki/Neuromyelitis_o
263ptica">neuromyelitis optica</a> since 2015.</p>
264</section>
265<section id="contact" class="level2">
266<h2 class="anchored" data-anchor-id="contact">Contact</h2>
267<ul>
268<li>Email: <a href="mailto:[email protected]">[email protected]</a></li>
269<li>LinkedIn: <a href="https://www.linkedin.com/in/chrisvoncsefalvay/">chrisvoncsefalvay</a></li>
270<li>GitHub: <a href="https://github.com/chrisvoncsefalvay">chrisvoncsefalvay</a></li>
271<li>ORCID: <a href="https://orcid.org/0000-0003-3131-0864">0000-0003-3131-0864</a></li>
272<li>Google Scholar: <a href="https://scholar.google.com/citations?user=X_2G-VsAAAAJ">X_2G-VsAAAAJ</a></li>
273</ul>
274
275
276</section>
277
278</main> <!-- /main -->
279<script id="quarto-html-after-body" type="application/javascript">
280  window.document.addEventListener("DOMContentLoaded", function (event) {
281    const icon = "";
282    const anchorJS = new window.AnchorJS();
283    anchorJS.options = {
284      placement: 'right',
285      icon: icon
286    };
287    anchorJS.add('.anchored');
288    const isCodeAnnotation = (el) => {
289      for (const clz of el.classList) {
290        if (clz.startsWith('code-annotation-')) {                     
291          return true;
292        }
293      }
294      return false;
295    }
296    const onCopySuccess = function(e) {
297      // button target
298      const button = e.trigger;
299      // don't keep focus
300      button.blur();
301      // flash "checked"
302      button.classList.add('code-copy-button-checked');
303      var currentTitle = button.getAttribute("title");
304      button.setAttribute("title", "Copied!");
305      let tooltip;
306      if (window.bootstrap) {
307        button.setAttribute("data-bs-toggle", "tooltip");
308        button.setAttribute("data-bs-placement", "left");
309        button.setAttribute("data-bs-title", "Copied!");
310        tooltip = new bootstrap.Tooltip(button, 
311          { trigger: "manual", 
312            customClass: "code-copy-button-tooltip",
313            offset: [0, -8]});
314        tooltip.show();    
315      }
316      setTimeout(function() {
317        if (tooltip) {
318          tooltip.hide();
319          button.removeAttribute("data-bs-title");
320          button.removeAttribute("data-bs-toggle");
321          button.removeAttribute("data-bs-placement");
322        }
323        button.setAttribute("title", currentTitle);
324        button.classList.remove('code-copy-button-checked');
325      }, 1000);
326      // clear code selection
327      e.clearSelection();
328    }
329    const getTextToCopy = function(trigger) {
330      const outerScaffold = trigger.parentElement.cloneNode(true);
331      const codeEl = outerScaffold.querySelector('code');
332      for (const childEl of codeEl.children) {
333        if (isCodeAnnotation(childEl)) {
334          childEl.remove();
335        }
336      }
337      return codeEl.innerText;
338    }
339    const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', {
340      text: getTextToCopy
341    });
342    clipboard.on('success', onCopySuccess);
343    if (window.document.getElementById('quarto-embedded-source-code-modal')) {
344      const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', {
345        text: getTextToCopy,
346        container: window.document.getElementById('quarto-embedded-source-code-modal')
347      });
348      clipboardModal.on('success', onCopySuccess);
349    }
350      var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//);
351      var mailtoRegex = new RegExp(/^mailto:/);
352        var filterRegex = new RegExp("https:\/\/chrisvoncsefalvay\.com");
353      var isInternal = (href) => {
354          return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href);
355      }
356      // Inspect non-navigation links and adorn them if external
357     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)');
358      for (var i=0; i<links.length; i++) {
359        const link = links[i];
360        if (!isInternal(link.href)) {
361          // undo the damage that might have been done by quarto-nav.js in the case of
362          // links that we want to consider external
363          if (link.dataset.originalHref !== undefined) {
364            link.href = link.dataset.originalHref;
365          }
366        }
367      }
368    function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
369      const config = {
370        allowHTML: true,
371        maxWidth: 500,
372        delay: 100,
373        arrow: false,
374        appendTo: function(el) {
375            return el.parentElement;
376        },
377        interactive: true,
378        interactiveBorder: 10,
379        theme: 'quarto',
380        placement: 'bottom-start',
381      };
382      if (contentFn) {
383        config.content = contentFn;
384      }
385      if (onTriggerFn) {
386        config.onTrigger = onTriggerFn;
387      }
388      if (onUntriggerFn) {
389        config.onUntrigger = onUntriggerFn;
390      }
391      window.tippy(el, config); 
392    }
393    const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
394    for (var i=0; i<noterefs.length; i++) {
395      const ref = noterefs[i];
396      tippyHover(ref, function() {
397        // use id or data attribute instead here
398        let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
399        try { href = new URL(href).hash; } catch {}
400        const id = href.replace(/^#\/?/, "");
401        const note = window.document.getElementById(id);
402        if (note) {
403          return note.innerHTML;
404        } else {
405          return "";
406        }
407      });
408    }
409    const xrefs = window.document.querySelectorAll('a.quarto-xref');
410    const processXRef = (id, note) => {
411      // Strip column container classes
412      const stripColumnClz = (el) => {
413        el.classList.remove("page-full", "page-columns");
414        if (el.children) {
415          for (const child of el.children) {
416            stripColumnClz(child);
417          }
418        }
419      }
420      stripColumnClz(note)
421      if (id === null || id.startsWith('sec-')) {
422        // Special case sections, only their first couple elements
423        const container = document.createElement("div");
424        if (note.children && note.children.length > 2) {
425          container.appendChild(note.children[0].cloneNode(true));
426          for (let i = 1; i < note.children.length; i++) {
427            const child = note.children[i];
428            if (child.tagName === "P" && child.innerText === "") {
429              continue;
430            } else {
431              container.appendChild(child.cloneNode(true));
432              break;
433            }
434          }
435          if (window.Quarto?.typesetMath) {
436            window.Quarto.typesetMath(container);
437          }
438          return container.innerHTML
439        } else {
440          if (window.Quarto?.typesetMath) {
441            window.Quarto.typesetMath(note);
442          }
443          return note.innerHTML;
444        }
445      } else {
446        // Remove any anchor links if they are present
447        const anchorLink = note.querySelector('a.anchorjs-link');
448        if (anchorLink) {
449          anchorLink.remove();
450        }
451        if (window.Quarto?.typesetMath) {
452          window.Quarto.typesetMath(note);
453        }
454        if (note.classList.contains("callout")) {
455          return note.outerHTML;
456        } else {
457          return note.innerHTML;
458        }
459      }
460    }
461    for (var i=0; i<xrefs.length; i++) {
462      const xref = xrefs[i];
463      tippyHover(xref, undefined, function(instance) {
464        instance.disable();
465        let url = xref.getAttribute('href');
466        let hash = undefined; 
467        if (url.startsWith('#')) {
468          hash = url;
469        } else {
470          try { hash = new URL(url).hash; } catch {}
471        }
472        if (hash) {
473          const id = hash.replace(/^#\/?/, "");
474          const note = window.document.getElementById(id);
475          if (note !== null) {
476            try {
477              const html = processXRef(id, note.cloneNode(true));
478              instance.setContent(html);
479            } finally {
480              instance.enable();
481              instance.show();
482            }
483          } else {
484            // See if we can fetch this
485            fetch(url.split('#')[0])
486            .then(res => res.text())
487            .then(html => {
488              const parser = new DOMParser();
489              const htmlDoc = parser.parseFromString(html, "text/html");
490              const note = htmlDoc.getElementById(id);
491              if (note !== null) {
492                const html = processXRef(id, note);
493                instance.setContent(html);
494              } 
495            }).finally(() => {
496              instance.enable();
497              instance.show();
498            });
499          }
500        } else {
501          // See if we can fetch a full url (with no hash to target)
502          // This is a special case and we should probably do some content thinning / targeting
503          fetch(url)
504          .then(res => res.text())
505          .then(html => {
506            const parser = new DOMParser();
507            const htmlDoc = parser.parseFromString(html, "text/html");
508            const note = htmlDoc.querySelector('main.content');
509            if (note !== null) {
510              // This should only happen for chapter cross references
511              // (since there is no id in the URL)
512              // remove the first header
513              if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
514                note.children[0].remove();
515              }
516              const html = processXRef(null, note);
517              instance.setContent(html);
518            } 
519          }).finally(() => {
520            instance.enable();
521            instance.show();
522          });
523        }
524      }, function(instance) {
525      });
526    }
527        let selectedAnnoteEl;
528        const selectorForAnnotation = ( cell, annotation) => {
529          let cellAttr = 'data-code-cell="' + cell + '"';
530          let lineAttr = 'data-code-annotation="' +  annotation + '"';
531          const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
532          return selector;
533        }
534        const selectCodeLines = (annoteEl) => {
535          const doc = window.document;
536          const targetCell = annoteEl.getAttribute("data-target-cell");
537          const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
538          const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
539          const lines = annoteSpan.getAttribute("data-code-lines").split(",");
540          const lineIds = lines.map((line) => {
541            return targetCell + "-" + line;
542          })
543          let top = null;
544          let height = null;
545          let parent = null;
546          if (lineIds.length > 0) {
547              //compute the position of the single el (top and bottom and make a div)
548              const el = window.document.getElementById(lineIds[0]);
549              top = el.offsetTop;
550              height = el.offsetHeight;
551              parent = el.parentElement.parentElement;
552            if (lineIds.length > 1) {
553              const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
554              const bottom = lastEl.offsetTop + lastEl.offsetHeight;
555              height = bottom - top;
556            }
557            if (top !== null && height !== null && parent !== null) {
558              // cook up a div (if necessary) and position it 
559              let div = window.document.getElementById("code-annotation-line-highlight");
560              if (div === null) {
561                div = window.document.createElement("div");
562                div.setAttribute("id", "code-annotation-line-highlight");
563                div.style.position = 'absolute';
564                parent.appendChild(div);
565              }
566              div.style.top = top - 2 + "px";
567              div.style.height = height + 4 + "px";
568              div.style.left = 0;
569              let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
570              if (gutterDiv === null) {
571                gutterDiv = window.document.createElement("div");
572                gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
573                gutterDiv.style.position = 'absolute';
574                const codeCell = window.document.getElementById(targetCell);
575                const gutter = codeCell.querySelector('.code-annotation-gutter');
576                gutter.appendChild(gutterDiv);
577              }
578              gutterDiv.style.top = top - 2 + "px";
579              gutterDiv.style.height = height + 4 + "px";
580            }
581            selectedAnnoteEl = annoteEl;
582          }
583        };
584        const unselectCodeLines = () => {
585          const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
586          elementsIds.forEach((elId) => {
587            const div = window.document.getElementById(elId);
588            if (div) {
589              div.remove();
590            }
591          });
592          selectedAnnoteEl = undefined;
593        };
594          // Handle positioning of the toggle
595      window.addEventListener(
596        "resize",
597        throttle(() => {
598          elRect = undefined;
599          if (selectedAnnoteEl) {
600            selectCodeLines(selectedAnnoteEl);
601          }
602        }, 10)
603      );
604      function throttle(fn, ms) {
605      let throttle = false;
606      let timer;
607        return (...args) => {
608          if(!throttle) { // first call gets through
609              fn.apply(this, args);
610              throttle = true;
611          } else { // all the others get throttled
612              if(timer) clearTimeout(timer); // cancel #2
613              timer = setTimeout(() => {
614                fn.apply(this, args);
615                timer = throttle = false;
616              }, ms);
617          }
618        };
619      }
620        // Attach click handler to the DT
621        const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
622        for (const annoteDlNode of annoteDls) {
623          annoteDlNode.addEventListener('click', (event) => {
624            const clickedEl = event.target;
625            if (clickedEl !== selectedAnnoteEl) {
626              unselectCodeLines();
627              const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
628              if (activeEl) {
629                activeEl.classList.remove('code-annotation-active');
630              }
631              selectCodeLines(clickedEl);
632              clickedEl.classList.add('code-annotation-active');
633            } else {
634              // Unselect the line
635              unselectCodeLines();
636              clickedEl.classList.remove('code-annotation-active');
637            }
638          });
639        }
640    const findCites = (el) => {
641      const parentEl = el.parentElement;
642      if (parentEl) {
643        const cites = parentEl.dataset.cites;
644        if (cites) {
645          return {
646            el,
647            cites: cites.split(' ')
648          };
649        } else {
650          return findCites(el.parentElement)
651        }
652      } else {
653        return undefined;
654      }
655    };
656    var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
657    for (var i=0; i<bibliorefs.length; i++) {
658      const ref = bibliorefs[i];
659      const citeInfo = findCites(ref);
660      if (citeInfo) {
661        tippyHover(citeInfo.el, function() {
662          var popup = window.document.createElement('div');
663          citeInfo.cites.forEach(function(cite) {
664            var citeDiv = window.document.createElement('div');
665            citeDiv.classList.add('hanging-indent');
666            citeDiv.classList.add('csl-entry');
667            var biblioDiv = window.document.getElementById('ref-' + cite);
668            if (biblioDiv) {
669              citeDiv.innerHTML = biblioDiv.innerHTML;
670            }
671            popup.appendChild(citeDiv);
672          });
673          return popup.innerHTML;
674        });
675      }
676    }
677  });
678  </script>
678
679</div> <!-- /content -->
680<footer class="footer">
681  <div class="nav-footer">
682    <div class="nav-footer-left">
683<ol start="3" type="a">
684<li>Chris von Csefalvay, 2011–. <a href="../disclaimer/">Disclaimer</a> · <a href="../privacy-policy/">Privacy</a> · <a href="../corrections/">Corrections</a></li>
685</ol>
686</div>   
687    <div class="nav-footer-center">
688      &nbsp;
689    </div>
690    <div class="nav-footer-right">
691      &nbsp;
692    </div>
693  </div>
694</footer>
695
696
697
698
699</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.