1<!DOCTYPE html> 2<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"><head> 3 4<meta charset="utf-8"> 5<meta name="generator" content="quarto-1.9.38"> 6 7<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 8 9 10<title>index â Jaehyun Song, Ph.D.</title> 11<style> 12/* Default styles provided by pandoc. 13** See https://pandoc.org/MANUAL.html#variables-for-html for config info. 14*/ 15code{white-space: pre-wrap;} 16span.smallcaps{font-variant: small-caps;} 17div.columns{display: flex; gap: min(4vw, 1.5em);} 18div.column{flex: auto; overflow-x: auto;} 19div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} 20ul.task-list{list-style: none;} 21ul.task-list li input[type="checkbox"] { 22 width: 0.8em; 23 margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */ 24 vertical-align: middle; 25} 26</style> 27 28
29<script src="../site_libs/quarto-nav/quarto-nav.js"></script>
vendor: 1 bytes, line 29
29
30<script src="../site_libs/quarto-nav/headroom.min.js"></script>
vendor: 1 bytes, line 30
30
31<script src="../site_libs/clipboard/clipboard.min.js"></script>
vendor: 1 bytes, line 31
31
32<script src="../site_libs/quarto-search/autocomplete.umd.js"></script>
vendor: 1 bytes, line 32
32
33<script src="../site_libs/quarto-search/fuse.min.js"></script>
vendor: 1 bytes, line 33
33
34<script src="../site_libs/quarto-search/quarto-search.js"></script>
34 35<meta name="quarto:offset" content="../"> 36<link href="../imgs/favicon.png" rel="icon" type="image/png">
37<script src="../site_libs/quarto-html/quarto.js" type="module"></script>
vendor: 1 bytes, line 37
37
38<script src="../site_libs/quarto-html/tabsets/tabsets.js" type="module"></script>
vendor: 1 bytes, line 38
38
39<script src="../site_libs/quarto-html/popper.min.js"></script>
vendor: 1 bytes, line 39
39
40<script src="../site_libs/quarto-html/tippy.umd.min.js"></script>
vendor: 1 bytes, line 40
40
41<script src="../site_libs/quarto-html/anchor.min.js"></script>
41 42<link href="../site_libs/quarto-html/tippy.css" rel="stylesheet"> 43<link href="../site_libs/quarto-html/quarto-syntax-highlighting-15634bcf2e68342d4ad2dfa704d543f6.css" rel="stylesheet" id="quarto-text-highlighting-styles">
44<script src="../site_libs/bootstrap/bootstrap.min.js"></script>
44 45<link href="../site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet"> 46<link href="../site_libs/bootstrap/bootstrap-930c6fd64aff15bdc301b294d59ae7ab.min.css" rel="stylesheet" append-hash="true" id="quarto-bootstrap" data-mode="light">
47<script id="quarto-search-options" type="application/json">{ 48 "location": "navbar", 49 "copy-button": false, 50 "collapse-after": 3, 51 "panel-placement": "end", 52 "type": "overlay", 53 "limit": 50, 54 "keyboard-shortcut": [ 55 "f", 56 "/", 57 "s" 58 ], 59 "show-item-context": false, 60 "language": { 61 "search-no-results-text": "No results", 62 "search-matching-documents-text": "matching documents", 63 "search-copy-link-title": "Copy link to search", 64 "search-hide-matches-text": "Hide additional matches", 65 "search-more-match-text": "more match in this document", 66 "search-more-matches-text": "more matches in this document", 67 "search-clear-button-title": "Clear", 68 "search-text-placeholder": "", 69 "search-detached-cancel-button-title": "Cancel", 70 "search-submit-button-title": "Submit", 71 "search-label": "ãµã¼ã" 72 } 73}</script>
vendor: 67 bytes, lines 73-74
73 74<script async="" src="https://www.googletagmanager.com/gtag/js?id=
74G-BCE61P2YP7
vendor: 13 bytes, lines 74-75
74"></script> 75
76<script type="text/javascript"> 77
vendor: 127 bytes, lines 78-81
78window.dataLayer = window.dataLayer || []; 79function gtag(){dataLayer.push(arguments);} 80gtag('js', new Date()); 81gtag('config', '
81G-BCE61P2YP7
vendor: 29 bytes, line 81
81', { 'anonymize_ip': true});
82</script>
82 83 84 85<link rel="stylesheet" href="../styles.css"> 86<meta property="og:title" content="Jaehyun Song, Ph.D."> 87<meta property="og:description" content="Jaehyun Songâs personal homepage"> 88<meta property="og:image" content="https://www.jaysong.net/cv/imgs/favicon.png"> 89<meta property="og:site_name" content="Jaehyun Song, Ph.D."> 90<meta name="twitter:title" content="Jaehyun Song, Ph.D."> 91<meta name="twitter:description" content="Jaehyun Songâs personal homepage"> 92<meta name="twitter:image" content="https://www.jaysong.net/cv/imgs/favicon.png"> 93<meta name="twitter:creator" content="@Tintstyle"> 94<meta name="twitter:site" content="@Tintstyle"> 95<meta name="twitter:card" content="summary"> 96</head> 97 98<body class="nav-fixed fullcontent quarto-light"> 99 100<div id="quarto-search-results"></div> 101 <header id="quarto-header" class="headroom fixed-top"> 102 <nav class="navbar navbar-expand-lg " data-bs-theme="dark"> 103 <div class="navbar-container container-fluid"> 104 <div class="navbar-brand-container mx-auto"> 105 <a href="../index.html" class="navbar-brand navbar-brand-logo"> 106 <img src="../imgs/logo.png" alt="" class="navbar-logo light-content"> 107 <img src="../imgs/logo.png" alt="" class="navbar-logo dark-content"> 108 </a> 109 <a class="navbar-brand" href="../index.html"> 110 <span class="navbar-title">Jaehyun Song, Ph.D.</span> 111 </a> 112 </div> 113 <div id="quarto-search" class="" title="ãµã¼ã"></div> 114 <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" role="menu" aria-expanded="false" aria-label="ããã²ã¼ã·ã§ã³ãåãæ¿ãã" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }"> 115 <span class="navbar-toggler-icon"></span> 116</button> 117 <div class="collapse navbar-collapse" id="navbarCollapse"> 118 <ul class="navbar-nav navbar-nav-scroll me-auto"> 119 <li class="nav-item"> 120 <a class="nav-link active" href="../cv/index.html" aria-current="page"> 121<span class="menu-text">CV</span></a> 122 </li> 123 <li class="nav-item"> 124 <a class="nav-link" href="../research/index.html"> 125<span class="menu-text">Research</span></a> 126 </li> 127 <li class="nav-item"> 128 <a class="nav-link" href="../teaching/index.html"> 129<span class="menu-text">Teaching</span></a> 130 </li> 131 <li class="nav-item dropdown "> 132 <a class="nav-link dropdown-toggle" href="#" id="nav-menu-seminar" role="link" data-bs-toggle="dropdown" aria-expanded="false"> 133 <span class="menu-text">Seminar</span> 134 </a> 135 <ul class="dropdown-menu" aria-labelledby="nav-menu-seminar"> 136 <li> 137 <a class="dropdown-item" href="../seminar/index.html"> 138 <span class="dropdown-text">å®ã¼ãã«ã¤ãã¦</span></a> 139 </li> 140 <li> 141 <a class="dropdown-item" href="../seminar/entry.html"> 142 <span class="dropdown-text">å¿åã«ã¤ãã¦</span></a> 143 </li> 144 <li> 145 <a class="dropdown-item" href="../seminar/faq.html"> 146 <span class="dropdown-text">ãããã質å</span></a> 147 </li> 148 <li> 149 <a class="dropdown-item" href="../seminar/people.html"> 150 <span class="dropdown-text">å®ã¼ãã®ã¡ã³ãã¼</span></a> 151 </li> 152 <li> 153 <a class="dropdown-item" href="../seminar/course.html"> 154 <span class="dropdown-text">ã¼ãçã®é²è·¯</span></a> 155 </li> 156 <li> 157 <a class="dropdown-item" href="../seminar/research.html"> 158 <span class="dropdown-text">ã¼ãçã®ç ç©¶ææ</span></a> 159 </li> 160 <li> 161 <a class="dropdown-item" href="../seminar/competition.html"> 162 <span class="dropdown-text">ããã¾ã§ã®åç</span></a> 163 </li> 164 <li> 165 <a class="dropdown-item" href="../seminar/preparation.html"> 166 <span class="dropdown-text">æ¥ä¼ã¿ã®éããæ¹</span></a> 167 </li> 168 <li> 169 <a class="dropdown-item" href="../seminar/about_song.html"> 170 <span class="dropdown-text">æ 彿å¡ã«ã¤ãã¦</span></a> 171 </li> 172 </ul> 173 </li> 174 <li class="nav-item"> 175 <a class="nav-link" href="../software/index.html"> 176<span class="menu-text">Software</span></a> 177 </li>
178 <li class="nav-item"> 179 <a class="nav-link" href="../notes/index.html"> 180<span class="menu-text">Notes</span></a> 181 </li> 182 <li class="nav-item"> 183 <a class="nav-link" href="../tutorial/index.html"> 184<span class="menu-text">Tutorials</span></a> 185 </li> 186</ul> 187 <ul class="navbar-nav navbar-nav-scroll ms-auto"> 188 <li class="nav-item compact"> 189 <a class="nav-link" href="https://github.com/JaehyunSong"> <i class="bi bi-github" role="img"> 190</i> 191<span class="menu-text"></span></a> 192 </li> 193 <li class="nav-item compact"> 194 <a class="nav-link" href="https://scholar.google.com/citations?user=8a-NxjkAAAAJ&hl=ja"> <i class="bi bi-google" role="img"> 195</i> 196<span class="menu-text"></span></a> 197 </li> 198 <li class="nav-item compact"> 199 <a class="nav-link" href="https://researchmap.jp/jaysong"> <i class="bi bi-mortarboard-fill" role="img"> 200</i> 201<span class="menu-text"></span></a> 202 </li> 203</ul> 204 </div> <!-- /navcollapse --> 205 <div class="quarto-navbar-tools"> 206</div> 207 </div> <!-- /container-fluid --> 208 </nav> 209</header> 210<!-- content --> 211<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar"> 212<!-- sidebar --> 213<!-- margin-sidebar --> 214 215<!-- main --> 216<main class="content" id="quarto-document-content"><header id="title-block-header" class="quarto-title-block"></header> 217 218 219 220 221<center> 222<span style="font-size:2em;">Jaehyun Song, Ph.D.</span> <br> Associate Professor in <a href="https://www.kansai-u.ac.jp/Fc_inf/">Faculty of Informatics</a>, <a href="https://www.kansai-u.ac.jp/">Kansai University</a>. <br><br> <!---Full CV is available [here](cv.pdf).---> 223</center> 224<section id="cv" class="level3"> 225<h3 class="anchored" data-anchor-id="cv">CV</h3> 226<p><a href="cv.pdf" class="btn btn-primary btn-sm" target="_blank" role="button"><i class="bi bi-window"></i> Open full CV in a new window</a></p> 227<!--- 228 229### Basic Information 230 231* Name(ENG): SONG Jaehyun 232* Name(KOR): ì¡ ì¬í 233* Name(JPN): å® è²¡æ³« (ã½ã³ ã¸ã§ãã§ã³) 234* Nationality: Republic of Korea 235* Birth: Seoul, Korea 236* Living: Osaka, Japan 237 238### Academic Position 239 240* **Apr. 2021 ~: Associate Professor, Kansai University** 241* Apr. 2020 ~ Mar.2021: Assistant Professor, Doshisha University 242* Apr. 2018 ~ Mar.2020: Assistant Professor, Waseda University 243* Partime Lecturer 244 * Kansai University: 2018 245 * Keio University: 2019 246 * Kobe University: 2018, 2019, 2020, 2021 247 * Kyoto Prefectural University: 2020, 2021 248 * Kyoto Womenâs University: 2016, 2017 249 * Osaka City University: 2017 250 * University of Tokyo: 2020 251 * Waseda University: 2021 252 253### Education 254 255* 2015~2018: Ph.D in Political Science (Kobe University) 256* 2012~2015: Master of Political Science (Kobe University) 257* 2006~2012: Bachelor of Law (Keio University) 258* 2002~2005: High School Diploma (High School Attached to College of Education, Dongguk University) 259 260### Skills 261 262* **Programming:** PHP and Python 263* **Statistical Computing:** R, Stata, SPSS, Stan, and Jags 264* **Agent-Based Modeling:** NetLogo 265* **Others:** $\LaTeX$, HTML + CSS, Markdown, Microsoft Office, LibreOffice, Apple iWork, Adobe Photoshop, and Final Cut Pro. 266 267---> 268</section> 269<section id="contact" class="level3"> 270<h3 class="anchored" data-anchor-id="contact">Contact</h3> 271<ul> 272<li>Mail: song [at] kansai-u.ac.jp</li> 273<li>Address 274<ul> 275<li>ã569-1095 大éªåºé«æ§»å¸éä»å¯ºçº2-1-1 276<ul> 277<li>å人ç 究室: TA227 (Aæ£2é)</li> 278</ul></li> 279<li>Ryozenji 2-1-1, Takatsuki, Osaka 569-1095, Japan 280<ul> 281<li>Office: TA227, Bldg. A (2nd floor)</li> 282</ul></li> 283</ul></li> 284<li>Access 285<ul> 286<li>髿§» (JR)ãææ´¥å¯ç° (JR)ãããã¹</li> 287<li>ã¿ã¯ã·ã¼ 288<ul> 289<li>髿§» (JR)ããç´2200åãææ´¥å¯ç° (JR)ããç´2000å</li> 290<li>åè) taxisite調ã¹</li> 291</ul></li> 292</ul></li> 293</ul> 294<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d1174.0599316566281!2d135.57685907010801!3d34.87797702268856!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x6000fdb89c6dd551%3A0xd3949eacf232a791!2z6Zai6KW_5aSn5a2m6auY5qe744Kt44Oj44Oz44OR44K5IOe3j-WQiOaDheWgseWtpumDqOODu-OCquODleOCo-OCuQ!5e0!3m2!1sja!2sjp!4v1634522963994!5m2!1sja!2sjp" width="600" height="450" style="border:0;" allowfullscreen="" loading="lazy"> 295</iframe> 296 297 298</section> 299 300</main> <!-- /main -->
301<script id="quarto-html-after-body" type="application/javascript"> 302 window.document.addEventListener("DOMContentLoaded", function (event) { 303 const icon = "î§"; 304 const anchorJS = new window.AnchorJS(); 305 anchorJS.options = { 306 placement: 'right', 307 icon: icon 308 }; 309 anchorJS.add('.anchored'); 310 const isCodeAnnotation = (el) => { 311 for (const clz of el.classList) { 312 if (clz.startsWith('code-annotation-')) { 313 return true; 314 } 315 } 316 return false; 317 } 318 const onCopySuccess = function(e) { 319 // button target 320 const button = e.trigger; 321 // don't keep focus 322 button.blur(); 323 // flash "checked" 324 button.classList.add('code-copy-button-checked'); 325 var currentTitle = button.getAttribute("title"); 326 button.setAttribute("title", "Copied!"); 327 let tooltip; 328 if (window.bootstrap) { 329 button.setAttribute("data-bs-toggle", "tooltip"); 330 button.setAttribute("data-bs-placement", "left"); 331 button.setAttribute("data-bs-title", "Copied!"); 332 tooltip = new bootstrap.Tooltip(button, 333 { trigger: "manual", 334 customClass: "code-copy-button-tooltip", 335 offset: [0, -8]}); 336 tooltip.show(); 337 } 338 setTimeout(function() { 339 if (tooltip) { 340 tooltip.hide(); 341 button.removeAttribute("data-bs-title"); 342 button.removeAttribute("data-bs-toggle"); 343 button.removeAttribute("data-bs-placement"); 344 } 345 button.setAttribute("title", currentTitle); 346 button.classList.remove('code-copy-button-checked'); 347 }, 1000); 348 // clear code selection 349 e.clearSelection(); 350 } 351 const getTextToCopy = function(trigger) { 352 const outerScaffold = trigger.parentElement.cloneNode(true); 353 const codeEl = outerScaffold.querySelector('code'); 354 for (const childEl of codeEl.children) { 355 if (isCodeAnnotation(childEl)) { 356 childEl.remove(); 357 } 358 } 359 return codeEl.innerText; 360 } 361 const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', { 362 text: getTextToCopy 363 }); 364 clipboard.on('success', onCopySuccess); 365 if (window.document.getElementById('quarto-embedded-source-code-modal')) { 366 const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', { 367 text: getTextToCopy, 368 container: window.document.getElementById('quarto-embedded-source-code-modal') 369 }); 370 clipboardModal.on('success', onCopySuccess); 371 } 372 var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//); 373 var mailtoRegex = new RegExp(/^mailto:/); 374 var filterRegex = new RegExp("https:\/\/www\.jaysong\.net\/"); 375 var isInternal = (href) => { 376 return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href); 377 } 378 // Inspect non-navigation links and adorn them if external 379 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)'); 380 for (var i=0; i<links.length; i++) { 381 const link = links[i]; 382 if (!isInternal(link.href)) { 383 // undo the damage that might have been done by quarto-nav.js in the case of 384 // links that we want to consider external 385 if (link.dataset.originalHref !== undefined) { 386 link.href = link.dataset.originalHref; 387 } 388 } 389 } 390 function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) { 391 const config = { 392 allowHTML: true, 393 maxWidth: 500, 394 delay: 100, 395 arrow: false, 396 appendTo: function(el) { 397 return el.parentElement; 398 }, 399 interactive: true, 400 interactiveBorder: 10, 401 theme: 'quarto', 402 placement: 'bottom-start', 403 }; 404 if (contentFn) { 405 config.content = contentFn; 406 } 407 if (onTriggerFn) { 408 config.onTrigger = onTriggerFn; 409 } 410 if (onUntriggerFn) { 411 config.onUntrigger = onUntriggerFn; 412 } 413 window.tippy(el, config); 414 } 415 const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]'); 416 for (var i=0; i<noterefs.length; i++) { 417 const ref = noterefs[i]; 418 tippyHover(ref, function() { 419 // use id or data attribute instead here 420 let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href'); 421 try { href = new URL(href).hash; } catch {} 422 const id = href.replace(/^#\/?/, ""); 423 const note = window.document.getElementById(id); 424 if (note) { 425 return note.innerHTML; 426 } else { 427 return ""; 428 } 429 }); 430 } 431 const xrefs = window.document.querySelectorAll('a.quarto-xref'); 432 const processXRef = (id, note) => { 433 // Strip column container classes 434 const stripColumnClz = (el) => { 435 el.classList.remove("page-full", "page-columns"); 436 if (el.children) { 437 for (const child of el.children) {
438 stripColumnClz(child); 439 } 440 } 441 } 442 stripColumnClz(note) 443 if (id === null || id.startsWith('sec-')) { 444 // Special case sections, only their first couple elements 445 const container = document.createElement("div"); 446 if (note.children && note.children.length > 2) { 447 container.appendChild(note.children[0].cloneNode(true)); 448 for (let i = 1; i < note.children.length; i++) { 449 const child = note.children[i]; 450 if (child.tagName === "P" && child.innerText === "") { 451 continue; 452 } else { 453 container.appendChild(child.cloneNode(true)); 454 break; 455 } 456 } 457 if (window.Quarto?.typesetMath) { 458 window.Quarto.typesetMath(container); 459 } 460 return container.innerHTML 461 } else { 462 if (window.Quarto?.typesetMath) { 463 window.Quarto.typesetMath(note); 464 } 465 return note.innerHTML; 466 } 467 } else { 468 // Remove any anchor links if they are present 469 const anchorLink = note.querySelector('a.anchorjs-link'); 470 if (anchorLink) { 471 anchorLink.remove(); 472 } 473 if (window.Quarto?.typesetMath) { 474 window.Quarto.typesetMath(note); 475 } 476 if (note.classList.contains("callout")) { 477 return note.outerHTML; 478 } else { 479 return note.innerHTML; 480 } 481 } 482 } 483 for (var i=0; i<xrefs.length; i++) { 484 const xref = xrefs[i]; 485 tippyHover(xref, undefined, function(instance) { 486 instance.disable(); 487 let url = xref.getAttribute('href'); 488 let hash = undefined; 489 if (url.startsWith('#')) { 490 hash = url; 491 } else { 492 try { hash = new URL(url).hash; } catch {} 493 } 494 if (hash) { 495 const id = hash.replace(/^#\/?/, ""); 496 const note = window.document.getElementById(id); 497 if (note !== null) { 498 try { 499 const html = processXRef(id, note.cloneNode(true)); 500 instance.setContent(html); 501 } finally { 502 instance.enable(); 503 instance.show(); 504 } 505 } else { 506 // See if we can fetch this 507 fetch(url.split('#')[0]) 508 .then(res => res.text()) 509 .then(html => { 510 const parser = new DOMParser(); 511 const htmlDoc = parser.parseFromString(html, "text/html"); 512 const note = htmlDoc.getElementById(id); 513 if (note !== null) { 514 const html = processXRef(id, note); 515 instance.setContent(html); 516 } 517 }).finally(() => { 518 instance.enable(); 519 instance.show(); 520 }); 521 } 522 } else { 523 // See if we can fetch a full url (with no hash to target) 524 // This is a special case and we should probably do some content thinning / targeting 525 fetch(url) 526 .then(res => res.text()) 527 .then(html => { 528 const parser = new DOMParser(); 529 const htmlDoc = parser.parseFromString(html, "text/html"); 530 const note = htmlDoc.querySelector('main.content'); 531 if (note !== null) { 532 // This should only happen for chapter cross references 533 // (since there is no id in the URL) 534 // remove the first header 535 if (note.children.length > 0 && note.children[0].tagName === "HEADER") { 536 note.children[0].remove(); 537 } 538 const html = processXRef(null, note); 539 instance.setContent(html); 540 } 541 }).finally(() => { 542 instance.enable(); 543 instance.show(); 544 }); 545 } 546 }, function(instance) { 547 }); 548 } 549 let selectedAnnoteEl; 550 const selectorForAnnotation = ( cell, annotation) => { 551 let cellAttr = 'data-code-cell="' + cell + '"'; 552 let lineAttr = 'data-code-annotation="' + annotation + '"'; 553 const selector = 'span[' + cellAttr + '][' + lineAttr + ']'; 554 return selector; 555 } 556 const selectCodeLines = (annoteEl) => { 557 const doc = window.document; 558 const targetCell = annoteEl.getAttribute("data-target-cell"); 559 const targetAnnotation = annoteEl.getAttribute("data-target-annotation"); 560 const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation)); 561 const lines = annoteSpan.getAttribute("data-code-lines").split(","); 562 const lineIds = lines.map((line) => { 563 return targetCell + "-" + line; 564 }) 565 let top = null; 566 let height = null; 567 let parent = null; 568 if (lineIds.length > 0) { 569 //compute the position of the single el (top and bottom and make a div) 570 const el = window.document.getElementById(lineIds[0]); 571 top = el.offsetTop; 572 height = el.offsetHeight; 573 parent = el.parentElement.parentElement; 574 if (lineIds.length > 1) { 575 const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]); 576 const bottom = lastEl.offsetTop + lastEl.offsetHeight; 577 height = bottom - top; 578 } 579 if (top !== null && height !== null && parent !== null) { 580 // cook up a div (if necessary) and position it 581 let div = window.document.getElementById("code-annotation-line-highlight"); 582 if (div === null) { 583 div = window.document.createElement("div"); 584 div.setAttribute("id", "code-annotation-line-highlight"); 585 div.style.position = 'absolute'; 586 parent.appendChild(div); 587 } 588 div.style.top = top - 2 + "px"; 589 div.style.height = height + 4 + "px"; 590 div.style.left = 0; 591 let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter"); 592 if (gutterDiv === null) { 593 gutterDiv = window.document.createElement("div"); 594 gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter"); 595 gutterDiv.style.position = 'absolute'; 596 const codeCell = window.document.getElementById(targetCell); 597 const gutter = codeCell.querySelector('.code-annotation-gutter'); 598 gutter.appendChild(gutterDiv); 599 } 600 gutterDiv.style.top = top - 2 + "px"; 601 gutterDiv.style.height = height + 4 + "px"; 602 } 603 selectedAnnoteEl = annoteEl; 604 } 605 }; 606 const unselectCodeLines = () => { 607 const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"]; 608 elementsIds.forEach((elId) => { 609 const div = window.document.getElementById(elId); 610 if (div) { 611 div.remove(); 612 } 613 }); 614 selectedAnnoteEl = undefined; 615 }; 616 // Handle positioning of the toggle 617 window.addEventListener( 618 "resize", 619 throttle(() => { 620 elRect = undefined; 621 if (selectedAnnoteEl) { 622 selectCodeLines(selectedAnnoteEl); 623 } 624 }, 10) 625 ); 626 function throttle(fn, ms) { 627 let throttle = false;
628 let timer; 629 return (...args) => { 630 if(!throttle) { // first call gets through 631 fn.apply(this, args); 632 throttle = true; 633 } else { // all the others get throttled 634 if(timer) clearTimeout(timer); // cancel #2 635 timer = setTimeout(() => { 636 fn.apply(this, args); 637 timer = throttle = false; 638 }, ms); 639 } 640 }; 641 } 642 // Attach click handler to the DT 643 const annoteDls = window.document.querySelectorAll('dt[data-target-cell]'); 644 for (const annoteDlNode of annoteDls) { 645 annoteDlNode.addEventListener('click', (event) => { 646 const clickedEl = event.target; 647 if (clickedEl !== selectedAnnoteEl) { 648 unselectCodeLines(); 649 const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active'); 650 if (activeEl) { 651 activeEl.classList.remove('code-annotation-active'); 652 } 653 selectCodeLines(clickedEl); 654 clickedEl.classList.add('code-annotation-active'); 655 } else { 656 // Unselect the line 657 unselectCodeLines(); 658 clickedEl.classList.remove('code-annotation-active'); 659 } 660 }); 661 } 662 const findCites = (el) => { 663 const parentEl = el.parentElement; 664 if (parentEl) { 665 const cites = parentEl.dataset.cites; 666 if (cites) { 667 return { 668 el, 669 cites: cites.split(' ') 670 }; 671 } else { 672 return findCites(el.parentElement) 673 } 674 } else { 675 return undefined; 676 } 677 }; 678 var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]'); 679 for (var i=0; i<bibliorefs.length; i++) { 680 const ref = bibliorefs[i]; 681 const citeInfo = findCites(ref); 682 if (citeInfo) { 683 tippyHover(citeInfo.el, function() { 684 var popup = window.document.createElement('div'); 685 citeInfo.cites.forEach(function(cite) { 686 var citeDiv = window.document.createElement('div'); 687 citeDiv.classList.add('hanging-indent'); 688 citeDiv.classList.add('csl-entry'); 689 var biblioDiv = window.document.getElementById('ref-' + cite); 690 if (biblioDiv) { 691 citeDiv.innerHTML = biblioDiv.innerHTML; 692 } 693 popup.appendChild(citeDiv); 694 }); 695 return popup.innerHTML; 696 }); 697 } 698 } 699 }); 700 </script>
700 701</div> <!-- /content --> 702<footer class="footer"> 703 <div class="nav-footer"> 704 <div class="nav-footer-left"> 705 706 </div> 707 <div class="nav-footer-center"> 708<p>Copyright 2026, Jaehyun Song</p> 709</div> 710 <div class="nav-footer-right"> 711 712 </div> 713 </div> 714</footer> 715 716 717 718 719</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.