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.7.27"> 6 7<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 8 9<meta name="description" content="Musings about science, technology, design, music and moreâ¦"> 10 11<title>Blog â XP Song</title> 12<style> 13code{white-space: pre-wrap;} 14span.smallcaps{font-variant: small-caps;} 15div.columns{display: flex; gap: min(4vw, 1.5em);} 16div.column{flex: auto; overflow-x: auto;} 17div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} 18ul.task-list{list-style: none;} 19ul.task-list li input[type="checkbox"] { 20 width: 0.8em; 21 margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */ 22 vertical-align: middle; 23} 24</style> 25 26
27<script src="site_libs/quarto-nav/quarto-nav.js"></script>
vendor: 1 bytes, line 27
27
28<script src="site_libs/quarto-nav/headroom.min.js"></script>
vendor: 1 bytes, line 28
28
29<script src="site_libs/clipboard/clipboard.min.js"></script>
vendor: 1 bytes, line 29
29
30<script src="site_libs/quarto-search/autocomplete.umd.js"></script>
vendor: 1 bytes, line 30
30
31<script src="site_libs/quarto-search/fuse.min.js"></script>
vendor: 1 bytes, line 31
31
32<script src="site_libs/quarto-search/quarto-search.js"></script>
32 33<meta name="quarto:offset" content="./"> 34<link href="./images/icon.png" rel="icon" type="image/png">
35<script src="site_libs/quarto-listing/list.min.js"></script>
vendor: 1 bytes, line 35
35
36<script src="site_libs/quarto-listing/quarto-listing.js"></script>
vendor: 1 bytes, line 36
36
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-985aa47af68dae11cd4d235c71fb941e.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-352d2168f5014ef2ecf06eb4ef66f56e.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 "language": { 60 "search-no-results-text": "No results", 61 "search-matching-documents-text": "matching documents", 62 "search-copy-link-title": "Copy link to search", 63 "search-hide-matches-text": "Hide additional matches", 64 "search-more-match-text": "more match in this document", 65 "search-more-matches-text": "more matches in this document", 66 "search-clear-button-title": "Clear", 67 "search-text-placeholder": "", 68 "search-detached-cancel-button-title": "Cancel", 69 "search-submit-button-title": "Submit", 70 "search-label": "Search" 71 } 72}</script>
vendor: 1 bytes, line 72
72
73<script> 74 75 window.document.addEventListener("DOMContentLoaded", function (_event) { 76 const listingTargetEl = window.document.querySelector('#listing-blog-posts .list'); 77 if (!listingTargetEl) { 78 // No listing discovered, do not attach. 79 return; 80 } 81 82 const options = { 83 valueNames: ['listing-image','listing-date','listing-title','listing-description',{ data: ['index'] },{ data: ['categories'] },{ data: ['listing-date-sort'] }], 84 85 searchColumns: ["listing-title","listing-author","listing-date","listing-image","listing-description","listing-categories"], 86 }; 87 88 window['quarto-listings'] = window['quarto-listings'] || {}; 89 window['quarto-listings']['listing-blog-posts'] = new List('listing-blog-posts', options); 90 91 if (window['quarto-listing-loaded']) { 92 window['quarto-listing-loaded'](); 93 } 94 }); 95 96 window.addEventListener('hashchange',() => { 97 if (window['quarto-listing-loaded']) { 98 window['quarto-listing-loaded'](); 99 } 100 }) 101 </script>
vendor: 67 bytes, lines 101-102
101 102<script async="" src="https://www.googletagmanager.com/gtag/js?id=
102G-WS5CZJ06W0
vendor: 13 bytes, lines 102-103
102"></script> 103
104<script type="text/javascript"> 105
vendor: 127 bytes, lines 106-109
106window.dataLayer = window.dataLayer || []; 107function gtag(){dataLayer.push(arguments);} 108gtag('js', new Date()); 109gtag('config', '
109G-WS5CZJ06W0
vendor: 29 bytes, line 109
109', { 'anonymize_ip': true});
110</script>
110 111<style> 112 113 .quarto-title-block .quarto-title-banner h1, 114 .quarto-title-block .quarto-title-banner h2, 115 .quarto-title-block .quarto-title-banner h3, 116 .quarto-title-block .quarto-title-banner h4, 117 .quarto-title-block .quarto-title-banner h5, 118 .quarto-title-block .quarto-title-banner h6 119 { 120 color: #ffffff; 121 } 122 123 .quarto-title-block .quarto-title-banner { 124 color: #ffffff; 125background-image: url(images/sheep.jpg); 126background-size: cover; 127 } 128</style> 129 130
130<script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=es6"></script>
130 131
131<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml-full.js" type="text/javascript"></script>
131 132
133<script type="text/javascript"> 134const typesetMath = (el) => { 135 if (window.MathJax) { 136 // MathJax Typeset 137 window.MathJax.typeset([el]); 138 } else if (window.katex) { 139 // KaTeX Render 140 var mathElements = el.getElementsByClassName("math"); 141 var macros = []; 142 for (var i = 0; i < mathElements.length; i++) { 143 var texText = mathElements[i].firstChild; 144 if (mathElements[i].tagName == "SPAN") { 145 window.katex.render(texText.data, mathElements[i], { 146 displayMode: mathElements[i].classList.contains('display'), 147 throwOnError: false, 148 macros: macros, 149 fleqn: false 150 }); 151 } 152 } 153 } 154} 155window.Quarto = { 156 typesetMath 157}; 158</script>
158 159 160<link rel="alternate" type="application/rss+xml" title="XP's Blog" href="blog.xml" data-external="1"><meta property="og:title" content="Blog"> 161<meta property="og:description" content="Musings about science, technology, design, music and moreâ¦"> 162<meta property="og:image" content="https://xpsong.com/posts/ai-strategy/featured.jpg"> 163<meta property="og:site_name" content="XP's Website"> 164<meta name="twitter:title" content="Blog"> 165<meta name="twitter:description" content="Musings about science, technology, design, music and moreâ¦"> 166<meta name="twitter:image" content="https://xpsong.com/posts/ai-strategy/featured.jpg"> 167<meta name="twitter:creator" content="@dr_watchnlearn"> 168<meta name="twitter:card" content="summary_large_image"> 169</head> 170 171<body class="nav-fixed quarto-light"> 172 173<div id="quarto-search-results"></div> 174 <header id="quarto-header" class="headroom fixed-top quarto-banner"> 175 <nav class="navbar navbar-expand-lg " data-bs-theme="dark"> 176 <div class="navbar-container container-fluid"> 177 <div class="navbar-brand-container mx-auto"> 178 <a href="./index.html" class="navbar-brand navbar-brand-logo"> 179 <img src="./images/icon.png" alt="XP's Website" class="navbar-logo"> 180 </a> 181 </div> 182 <div id="quarto-search" class="" title="Search"></div> 183 <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(); }"> 184 <span class="navbar-toggler-icon"></span> 185</button> 186 <div class="collapse navbar-collapse" id="navbarCollapse"> 187 <ul class="navbar-nav navbar-nav-scroll ms-auto"> 188 <li class="nav-item"> 189 <a class="nav-link" href="./courses.html"> 190<span class="menu-text">Courses</span></a> 191 </li> 192 <li class="nav-item"> 193 <a class="nav-link active" href="./blog.html" aria-current="page"> 194<span class="menu-text">Blog</span></a> 195 </li> 196 <li class="nav-item"> 197 <a class="nav-link" href="./academia.html"> 198<span class="menu-text">Academia</span></a> 199 </li> 200 <li class="nav-item"> 201 <a class="nav-link" href="./music.html"> 202<span class="menu-text">Music</span></a> 203 </li> 204</ul> 205 </div> <!-- /navcollapse --> 206 <div class="quarto-navbar-tools"> 207</div> 208 </div> <!-- /container-fluid --> 209 </nav> 210</header> 211<!-- content --> 212<header id="title-block-header" class="quarto-title-block default page-columns page-full"> 213 <div class="quarto-title-banner page-columns page-full"> 214 <div class="quarto-title column-page-left"> 215 <h1 class="title">Blog</h1> 216 <div> 217 <div class="description"> 218 Musings about science, technology, design, music and more⦠219 </div> 220 </div> 221 </div> 222 </div> 223 224 225 <div class="quarto-title-meta column-page-left"> 226 227 228 229 230 </div> 231 232 233 </header><div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-full page-navbar"> 234<!-- sidebar --> 235<!-- margin-sidebar --> 236 <div id="quarto-margin-sidebar" class="sidebar margin-sidebar"> 237 238 <h5 class="quarto-listing-category-title">Categories</h5><div class="quarto-listing-category category-default"><div class="category" data-category="">All <span class="quarto-category-count">(16)</span></div><div class="category" data-category="Q3VsdHVyZQ==">Culture <span class="quarto-category-count">(1)</span></div><div class="category" data-category="RGVzaWdu">Design <span class="quarto-category-count">(2)</span></div><div class="category" data-category="TXVzaWM=">Music <span class="quarto-category-count">(2)</span></div><div class="category" data-category="Ug==">R <span class="quarto-category-count">(8)</span></div><div class="category" data-category="UmVzZWFyY2g=">Research <span class="quarto-category-count">(6)</span></div><div class="category" data-category="U2NpZW5jZQ==">Science <span class="quarto-category-count">(6)</span></div><div class="category" data-category="U29mdHdhcmU=">Software <span class="quarto-category-count">(5)</span></div><div class="category" data-category="VGVjaG5vbG9neQ==">Technology <span class="quarto-category-count">(2)</span></div><div class="category" data-category="VHV0b3JpYWxz">Tutorials <span class="quarto-category-count">(6)</span></div><div class="category" data-category="V2F0Y2hlcw==">Watches <span class="quarto-category-count">(1)</span></div></div></div> 239<!-- main --> 240<main class="content quarto-banner-title-block column-page-left" id="quarto-document-content"> 241 242 243 244 245 246<style> 247 248#title-block-header { 249 margin-block-end: -20rem; 250 position: relative;
251 margin-top: -1px; 252 height: 800px; 253} 254 255.quarto-title-banner { 256 margin-block-end: 1rem; 257 position: relative; 258 margin-top: -1px; 259 height: 85%; 260 text-transform: none; 261} 262 263.nav-footer { 264 background-color: white; 265} 266 267h1.title { 268 font-size: 2.5rem; 269 color: #FFFFFF; 270} 271 272</style> 273<div id="listing-blog-posts" class="quarto-listing quarto-listing-container-grid"> 274<div class="listing-actions-group"> 275 <div class="input-group input-group-sm quarto-listing-sort"> 276 <span class="input-group-text"><i class="bi bi-sort-down"></i></span> 277 <select id="listing-blog-posts-sort" class="form-select" aria-label="Order By" onchange="window['quarto-listings']['listing-blog-posts'].sort(this.options[this.selectedIndex].value, { order: this.options[this.selectedIndex].getAttribute('data-direction')})"> 278 <option value="" disabled="" selected="" hidden="">Order By</option> 279 <option value="index" data-direction="asc">Default</option> 280 <option value="listing-title" data-direction="asc"> 281 Title 282 </option> 283 <option value="listing-date-sort" data-direction="asc"> 284 Date - Oldest 285 </option> 286 <option value="listing-date-sort" data-direction="desc"> 287 Date - Newest 288 </option> 289 </select> 290 </div> 291 <div class="input-group input-group-sm quarto-listing-filter"> 292 <span class="input-group-text"><i class="bi bi-search"></i></span> 293 <input type="text" class="search form-control" placeholder="Filter"> 294 </div> 295</div> 296<div class="list grid quarto-listing-cols-3"> 297<div class="g-col-1" data-index="0" data-categories="U29mdHdhcmUlMkNUZWNobm9sb2d5JTJDQ3VsdHVyZQ==" data-listing-date-sort="1744473600000" data-listing-file-modified-sort="1762009545914" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="16" data-listing-word-count-sort="3114"> 298<a href="./posts/ai-strategy/index.html" class="quarto-grid-link"> 299<div class="quarto-grid-item card h-100 card-left"> 300<p class="card-img-top"> 301<img loading="lazy" src="./posts/ai-strategy/featured.jpg" class="thumbnail-image card-img" style="height: 8em;"> 302</p> 303<div class="card-body post-contents"> 304<h5 class="no-anchor card-title listing-title"> 305Vibe Coding with AI Tools in Large Enterprises 306</h5> 307<div class="card-text listing-description delink"> 308<p>Re-thinking how we work, learn, and organize ourselves</p> 309</div> 310<div class="card-attribution card-text-small end"> 311<div class="listing-date"> 312Apr 13, 2025 313</div> 314</div> 315</div> 316</div></a> 317</div> 318<div class="g-col-1" data-index="1" data-categories="RGVzaWduJTJDV2F0Y2hlcw==" data-listing-date-sort="1734192000000" data-listing-file-modified-sort="1745066724193" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="6" data-listing-word-count-sort="1064"> 319<a href="./posts/watch-n-learn/index.html" class="quarto-grid-link"> 320<div class="quarto-grid-item card h-100 card-left"> 321<p class="card-img-top"> 322<img loading="lazy" src="./posts/watch-n-learn/featured.jpg" class="thumbnail-image card-img" style="height: 8em;"> 323</p> 324<div class="card-body post-contents"> 325<h5 class="no-anchor card-title listing-title"> 326Modding watches, sharing the process 327</h5> 328<div class="card-text listing-description delink"> 329<p>My new Instagram channel <span class="citation" data-cites="dr.watchnlearn">@dr.watchnlearn</span> is now live!</p> 330</div> 331<div class="card-attribution card-text-small end"> 332<div class="listing-date"> 333Dec 15, 2024 334</div> 335</div> 336</div> 337</div></a> 338</div> 339<div class="g-col-1" data-index="2" data-categories="VHV0b3JpYWxzJTJDU29mdHdhcmUlMkNS" data-listing-date-sort="1698768000000" data-listing-file-modified-sort="1701242788654" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="2" data-listing-word-count-sort="230"> 340<a href="./posts/geospatial-datascience-r/index.html" class="quarto-grid-link"> 341<div class="quarto-grid-item card h-100 card-left"> 342<p class="card-img-top"> 343<img loading="lazy" src="./posts/geospatial-datascience-r/featured.jpg" class="thumbnail-image card-img" style="height: 8em;"> 344</p> 345<div class="card-body post-contents"> 346<h5 class="no-anchor card-title listing-title"> 347New Online Course: Geospatial Data Science with R 348</h5> 349<div class="card-text listing-description delink"> 350<p>Learn the skills to work effectively with spatial data for real-world applications. No prior coding experience required.</p> 351</div> 352<div class="card-attribution card-text-small end"> 353<div class="listing-date"> 354Nov 1, 2023 355</div> 356</div> 357</div> 358</div></a> 359</div> 360<div class="g-col-1" data-index="3" data-categories="UiUyQ1Jlc2VhcmNoJTJDU29mdHdhcmUlMkNTY2llbmNl" data-listing-date-sort="1659283200000" data-listing-file-modified-sort="1745070660386" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="11" data-listing-word-count-sort="2156"> 361<a href="./posts/biodivercity/index.html" class="quarto-grid-link"> 362<div class="quarto-grid-item card h-100 card-left"> 363<p class="card-img-top"> 364<img loading="lazy" src="./posts/biodivercity/featured.jpg" class="thumbnail-image card-img" style="height: 8em;" alt="Image by Ivan Bandura from Unsplash"> 365</p> 366<div class="card-body post-contents"> 367<h5 class="no-anchor card-title listing-title"> 368Biodiversity in cities: How can we assess the âperformanceâ of urban developments? 369</h5> 370<div class="card-text listing-description delink"> 371<p>We need a predictive approach that compares between present and future scenarios</p> 372</div> 373<div class="card-attribution card-text-small end"> 374<div class="listing-date"> 375Aug 1, 2022 376</div> 377</div> 378</div> 379</div></a> 380</div> 381<div class="g-col-1" data-index="4" data-categories="TXVzaWM=" data-listing-date-sort="1641744000000" data-listing-file-modified-sort="1701242788888" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="1" data-listing-word-count-sort="30"> 382<a href="./posts/nathans-first-drumset/index.html" class="quarto-grid-link"> 383<div class="quarto-grid-item card h-100 card-left"> 384<p class="card-img-top"> 385<img loading="lazy" src="./posts/nathans-first-drumset/featured.jpg" class="thumbnail-image card-img" style="height: 8em;"> 386</p> 387<div class="card-body post-contents"> 388<h5 class="no-anchor card-title listing-title"> 389Nathanâs first drumset 390</h5> 391<div class="card-text listing-description delink"> 392<p>Son got his first drumset as a gift⦠and I had a brainwave</p> 393</div> 394<div class="card-attribution card-text-small end"> 395<div class="listing-date"> 396Jan 10, 2022 397</div> 398</div> 399</div> 400</div></a> 401</div> 402<div class="g-col-1" data-index="5" data-categories="UiUyQ1Jlc2VhcmNoJTJDU29mdHdhcmUlMkNTY2llbmNl" data-listing-date-sort="1626364800000" data-listing-file-modified-sort="1745070587221" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="20" data-listing-word-count-sort="3949"> 403<a href="./posts/home2park/index.html" class="quarto-grid-link"> 404<div class="quarto-grid-item card h-100 card-left"> 405<p class="card-img-top"> 406<img loading="lazy" src="./posts/home2park/featured.jpg" class="thumbnail-image card-img" style="height: 8em;" alt="Image by Pexels from Pixabay"> 407</p> 408<div class="card-body post-contents"> 409<h5 class="no-anchor card-title listing-title"> 410Trying to fight cabin fever? The types of parks near your home matters 411</h5> 412<div class="card-text listing-description delink"> 413<p>We need better ways to measure our access to parks and outdoor space
413s</p> 414</div> 415<div class="card-attribution card-text-small end"> 416<div class="listing-date"> 417Jul 16, 2021 418</div> 419</div> 420</div> 421</div></a> 422</div> 423<div class="g-col-1" data-index="6" data-categories="UiUyQ1Jlc2VhcmNoJTJDVHV0b3JpYWxzJTJDU2NpZW5jZQ==" data-listing-date-sort="1615478400000" data-listing-file-modified-sort="1745069532385" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="20" data-listing-word-count-sort="3833"> 424<a href="./posts/city-landcover-change/index.html" class="quarto-grid-link"> 425<div class="quarto-grid-item card h-100 card-left"> 426<p class="card-img-top"> 427<img loading="lazy" src="./posts/city-landcover-change/featured.jpg" class="thumbnail-image card-img" style="height: 8em;" alt="Image by Alexey Topolyanskiy from Unsplash"> 428</p> 429<div class="card-body post-contents"> 430<h5 class="no-anchor card-title listing-title"> 431Changes in a cityâs land cover over time 432</h5> 433<div class="card-text listing-description delink"> 434<p>Using publicly-available satellite data to measure land cover change</p> 435</div> 436<div class="card-attribution card-text-small end"> 437<div class="listing-date"> 438Mar 12, 2021 439</div> 440</div> 441</div> 442</div></a> 443</div> 444<div class="g-col-1" data-index="7" data-categories="TXVzaWMlMkNUZWNobm9sb2d5" data-listing-date-sort="1586016000000" data-listing-file-modified-sort="1745050686794" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="2" data-listing-word-count-sort="226"> 445<a href="./posts/zoom-drum-lessons/index.html" class="quarto-grid-link"> 446<div class="quarto-grid-item card h-100 card-left"> 447<p class="card-img-top"> 448<img loading="lazy" src="./posts/zoom-drum-lessons/featured.jpg" class="thumbnail-image card-img" style="height: 8em;"> 449</p> 450<div class="card-body post-contents"> 451<h5 class="no-anchor card-title listing-title"> 452Zoom with Drums 453</h5> 454<div class="card-text listing-description delink"> 455<p>Exploring different ways to set up for online music lessons</p> 456</div> 457<div class="card-attribution card-text-small end"> 458<div class="listing-date"> 459Apr 5, 2020 460</div> 461</div> 462</div> 463</div></a> 464</div> 465<div class="g-col-1" data-index="8" data-categories="UiUyQ1R1dG9yaWFscyUyQ1NjaWVuY2U=" data-listing-date-sort="1580486400000" data-listing-file-modified-sort="1745067024111" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="2" data-listing-word-count-sort="225"> 466<a href="./posts/intro2r-spatial/index.html" class="quarto-grid-link"> 467<div class="quarto-grid-item card h-100 card-left"> 468<p class="card-img-top"> 469<img loading="lazy" src="./posts/intro2r-spatial/featured.jpg" class="thumbnail-image card-img" style="height: 8em;" alt="Satellite image of Singapore. Image derived from Landsat-8 (USGS, 2018)."> 470</p> 471<div class="card-body post-contents"> 472<h5 class="no-anchor card-title listing-title"> 473Analysing spatial patterns of the landscape 474</h5> 475<div class="card-text listing-description delink"> 476<p>Classify land cover and quantify landscape configuration</p> 477</div> 478<div class="card-attribution card-text-small end"> 479<div class="listing-date"> 480Feb 1, 2020 481</div> 482</div> 483</div> 484</div></a> 485</div> 486<div class="g-col-1" data-index="9" data-categories="UiUyQ1Jlc2VhcmNoJTJDVHV0b3JpYWxz" data-listing-date-sort="1578412800000" data-listing-file-modified-sort="1701242788889" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="12" data-listing-word-count-sort="2249"> 487<a href="./posts/photo-classify/index.html" class="quarto-grid-link"> 488<div class="quarto-grid-item card h-100 card-left"> 489<p class="card-img-top"> 490<img loading="lazy" src="./posts/photo-classify/featured.png" class="thumbnail-image card-img" style="height: 8em;"> 491</p> 492<div class="card-body post-contents"> 493<h5 class="no-anchor card-title listing-title"> 494Automated image classification into content-type categories 495</h5> 496<div class="card-text listing-description delink"> 497<p>Classify images based on keywords generated from the Google Cloud Vision API</p> 498</div> 499<div class="card-attribution card-text-small end"> 500<div class="listing-date"> 501Jan 8, 2020 502</div> 503</div> 504</div> 505</div></a> 506</div> 507<div class="g-col-1" data-index="10" data-categories="UiUyQ1R1dG9yaWFscw==" data-listing-date-sort="1562860800000" data-listing-file-modified-sort="1701242788758" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="1" data-listing-word-count-sort="128"> 508<a href="./posts/intro2r/index.html" class="quarto-grid-link"> 509<div class="quarto-grid-item card h-100 card-left"> 510<p class="card-img-top"> 511<img loading="lazy" src="./posts/intro2r/featured.png" class="thumbnail-image card-img" style="height: 8em;"> 512</p> 513<div class="card-body post-contents"> 514<h5 class="no-anchor card-title listing-title"> 515A crash course in R programming 516</h5> 517<div class="card-text listing-description delink"> 518<p>For those without coding experience</p> 519</div> 520<div class="card-attribution card-text-small end"> 521<div class="listing-date"> 522Jul 12, 2019 523</div> 524</div> 525</div> 526</div></a> 527</div> 528<div class="g-col-1" data-index="11" data-categories="VHV0b3JpYWxz" data-listing-date-sort="1560528000000" data-listing-file-modified-sort="1701242788899" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="3" data-listing-word-count-sort="485"> 529<a href="./posts/trackchange-word/index.html" class="quarto-grid-link"> 530<div class="quarto-grid-item card h-100 card-left"> 531<p class="card-img-top"> 532<img loading="lazy" src="./posts/trackchange-word/featured.jpg" class="thumbnail-image card-img" style="height: 8em;" alt="Image by Ulrike Leone from Pixabay"> 533</p> 534<div class="card-body post-contents"> 535<h5 class="no-anchor card-title listing-title"> 536How to clean up âtracked changesâ in Word without going insane 537</h5> 538<div class="card-text listing-description delink"> 539<p>Microsoft Word Macro to accept and highlight all tracked changes</p> 540</div> 541<div class="card-attribution card-text-small end"> 542<div class="listing-date"> 543Jun 15, 2019 544</div> 545</div> 546</div> 547</div></a> 548</div> 549<div class="g-col-1" data-index="12" data-categories="UiUyQ1Jlc2VhcmNoJTJDU29mdHdhcmUlMkNTY2llbmNl" data-listing-date-sort="1522512000000" data-listing-file-modified-sort="1745066922995" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="3" data-listing-word-count-sort="468"> 550<a href="./posts/street-trees/index.html" class="quarto-grid-link"> 551<div class="quarto-grid-item card h-100 card-left"> 552<p class="card-img-top"> 553<img loading="lazy" src="./posts/street-trees/featured.jpg" class="thumbnail-image card-img" style="height: 8em;" alt="Commonwealth region, Singapore. Photo by Phillip Urech, 2017"> 554</p> 555<div class="card-body post-contents"> 556<h5 class="no-anchor card-title listing-title"> 557The performance of city trees 558</h5> 559<div class="card-text listing-description delink"> 560<p>
560Develop allometric equations for tree size and structure</p> 561</div> 562<div class="card-attribution card-text-small end"> 563<div class="listing-date"> 564Apr 1, 2018 565</div> 566</div> 567</div> 568</div></a> 569</div> 570<div class="g-col-1" data-index="13" data-categories="RGVzaWdu" data-listing-date-sort="1487952000000" data-listing-file-modified-sort="1701242788888" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="1" data-listing-word-count-sort="169"> 571<a href="./posts/kashiwanoha/index.html" class="quarto-grid-link"> 572<div class="quarto-grid-item card h-100 card-left"> 573<p class="card-img-top"> 574<img loading="lazy" src="./posts/kashiwanoha/featured.jpg" class="thumbnail-image card-img" style="height: 8em;" alt="Proposed design for LALAPORT Plaza. Kashiwanoha, Japan"> 575</p> 576<div class="card-body post-contents"> 577<h5 class="no-anchor card-title listing-title"> 578âKashiwanoha Smart Cityâ design workshop 579</h5> 580<div class="card-text listing-description delink"> 581<p>Collaboration between Tsinghua University, National University of Singapore and Chiba University</p> 582</div> 583<div class="card-attribution card-text-small end"> 584<div class="listing-date"> 585Feb 25, 2017 586</div> 587</div> 588</div> 589</div></a> 590</div> 591<div class="g-col-1" data-index="14" data-categories="UmVzZWFyY2glMkNTY2llbmNl" data-listing-date-sort="1459440000000" data-listing-file-modified-sort="1745066887603" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="2" data-listing-word-count-sort="319"> 592<a href="./posts/urban-agriculture/index.html" class="quarto-grid-link"> 593<div class="quarto-grid-item card h-100 card-left"> 594<p class="card-img-top"> 595<img loading="lazy" src="./posts/urban-agriculture/featured.jpg" class="thumbnail-image card-img" style="height: 8em;" alt="Image by BrightAgrotech from Pixabay"> 596</p> 597<div class="card-body post-contents"> 598<h5 class="no-anchor card-title listing-title"> 599Feasibility of urban farming in compact cities 600</h5> 601<div class="card-text listing-description delink"> 602<p>Done with the Honours Thesis!</p> 603</div> 604<div class="card-attribution card-text-small end"> 605<div class="listing-date"> 606Apr 1, 2016 607</div> 608</div> 609</div> 610</div></a> 611</div> 612<div class="g-col-1" data-index="15" data-listing-date-sort="1451577600000" data-listing-file-modified-sort="1701242788654" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="2" data-listing-word-count-sort="281"> 613<a href="./posts/hello/index.html" class="quarto-grid-link"> 614<div class="quarto-grid-item card h-100 card-left"> 615<p class="card-img-top"> 616<img loading="lazy" src="./posts/hello/featured.jpg" class="thumbnail-image card-img" style="height: 8em;" alt="Hello"> 617</p> 618<div class="card-body post-contents"> 619<h5 class="no-anchor card-title listing-title"> 620Hello 621</h5> 622<div class="card-text listing-description delink"> 623<p>Well⦠I finally did it. I started a website. And a blog.</p> 624</div> 625<div class="card-attribution card-text-small end"> 626<div class="listing-date"> 627Jan 1, 2016 628</div> 629</div> 630</div> 631</div></a> 632</div> 633</div> 634<div class="listing-no-matching d-none">No matching items</div> 635</div> 636<p><br><br></p> 637<style type="text/css">@import url("https://assets.mlcdn.com/fonts.css?version=1690874");</style> 638 <style type="text/css"> 639 /* LOADER */ 640 .ml-form-embedSubmitLoad { 641 display: inline-block; 642 width: 20px; 643 height: 20px; 644 } 645 646 .g-recaptcha { 647 transform: scale(1); 648 -webkit-transform: scale(1); 649 transform-origin: 0 0; 650 -webkit-transform-origin: 0 0; 651 height: ; 652 } 653 654 .sr-only { 655 position: absolute; 656 width: 1px; 657 height: 1px; 658 padding: 0; 659 margin: -1px; 660 overflow: hidden; 661 clip: rect(0,0,0,0); 662 border: 0; 663 } 664 665 .ml-form-embedSubmitLoad:after { 666 content: " "; 667 display: block; 668 width: 11px; 669 height: 11px; 670 margin: 1px; 671 border-radius: 50%; 672 border: 4px solid #fff; 673 border-color: #ffffff #ffffff #ffffff transparent; 674 animation: ml-form-embedSubmitLoad 1.2s linear infinite; 675 } 676 @keyframes ml-form-embedSubmitLoad { 677 0% { 678 transform: rotate(0deg); 679 } 680 100% { 681 transform: rotate(360deg); 682 } 683 } 684 #mlb2-6731035.ml-form-embedContainer { 685 box-sizing: border-box; 686 display: table; 687 margin: 0 auto; 688 position: static; 689 width: 100% !important; 690 } 691 #mlb2-6731035.ml-form-embedContainer h4, 692 #mlb2-6731035.ml-form-embedContainer p, 693 #mlb2-6731035.ml-form-embedContainer span, 694 #mlb2-6731035.ml-form-embedContainer button { 695 text-transform: none !important; 696 letter-spacing: normal !important; 697 } 698 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper { 699 background-color: #f2f2f2; 700 701 border-width: 0px; 702 border-color: transparent; 703 border-radius: 19px; 704 border-style: solid; 705 box-sizing: border-box; 706 display: inline-block !important; 707 margin: 0; 708 padding: 0; 709 position: relative; 710 } 711 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper.embedPopup, 712 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper.embedDefault { width: 900px; } 713 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper.embedForm { max-width: 900px; width: 100%; } 714 #mlb2-6731035.ml-form-embedContainer .ml-form-align-left { text-align: left; } 715 #mlb2-6731035.ml-form-embedContainer .ml-form-align-center { text-align: center; } 716 #mlb2-6731035.ml-form-embedContainer .ml-form-align-default { display: table-cell !important; vertical-align: middle !important; text-align: center !important; } 717 #mlb2-6731035.ml-form-embedContainer .ml-form-align-right { text-align: right; } 718 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedHeader img { 719 border-top-left-radius: 19px; 720 border-top-right-radius: 19px; 721 height: auto; 722 margin: 0 auto !important; 723 max-width: 100%; 724 width: undefinedpx; 725 } 726 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody, 727 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-successBody { 728 padding: 20px 20px 0 20px; 729 } 730 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody.ml-form-embedBodyHorizontal { 731 padding-bottom: 0; 732 } 733 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-embedContent, 734 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-successBody .ml-form-successContent { 735 text-align: left; 736 margin: 0 0 20px 0; 737 } 738 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-embedContent h4, 739 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-successBody .ml-form-successContent h4 { 740 color: #1a1a1a; 741 font-family: 'Raleway', sans-serif; 742 font-size: 24px; 743 font-weight: 700; 744 margin: 0 0 10px 0; 745 text-align: center; 746 word-break: break-word; 747 } 748 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-embedContent p, 749 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-successBody .ml-form-successContent p { 750 color: #343a40; 751 font-family: 'Raleway', sans-serif; 752 font-size: 18px; 753 font-weight: 400; 754 line-height: 24px; 755 margin: 0 0 10px 0; 756 text-align: center; 757 } 758 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-embedContent ul, 759 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-embedContent ol, 760 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-successBody .ml-form-successContent ul, 761 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-successBody .ml-form-successContent ol { 762 color: #343a40; 763 font-family: 'Raleway', sans-serif; 764 font-size: 18px; 765 } 766 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-embedContent ol ol, 767 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-successBody .ml-form-successContent ol ol { 768 list-style-type: lower-alpha; 769 } 770 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-embedContent ol ol ol, 771 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-successBody .ml-form-successContent ol ol ol { 772 list-style-type: lower-roman; 773 } 774 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-embedContent p a, 775 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-successBody .ml-form-successContent p a { 776 color: #343a40; 777 text-decoration: underline; 778 } 779 780 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-block-form .ml-field-group { 781 text-align: left!important; 782 } 783 784 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-block-form .ml-field-group label { 785 margin-bottom: 5px; 786 color: #333333; 787 font-size: 14px; 788 font-family: 'Open Sans', Arial, Helvetica, sans-serif; 789 font-weight: bold; font-style: normal; text-decoration: none;; 790 display: inline-block; 791 line-height: 20px; 792 } 793 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-embedContent p:last-child, 794 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-successBody .ml-form-successContent p:last-child { 795 margin: 0; 796 } 797 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody form { 798 margin: 0; 799 width: 100%; 800 } 801 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-formContent, 802 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-checkboxRow { 803 margin: 0 0 20px 0; 804 width: 100%; 805 } 806 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-checkboxRow { 807 float: left; 808 } 809 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-formContent.horozintalForm { 810 margin: 0; 811 padding: 0 0 20px 0; 812 width: 100%; 813 height: auto; 814 float: left; 815 } 816 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow { 817 margin: 0 0 10px 0; 818 width: 100%; 819 } 820 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow.ml-last-item { 821 margin: 0; 822 } 823 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow.ml-formfieldHorizintal { 824 margin: 0; 825 } 826 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow input { 827 background-color: #ffffff !important; 828 color: #333333 !important; 829 border-color: #cccccc; 830 border-radius: 4px !important; 831 border-style: solid !important; 832 border-width: 1px !important; 833 font-family: 'Open Sans', Arial, Helvetica, sans-serif; 834 font-size: 12px !important; 835 height: auto; 836 line-height: 21px !important; 837 margin-bottom: 0; 838 margin-top: 0; 839 margin-left: 0; 840 margin-right: 0; 841 padding: 10px 10px !important; 842 width: 100% !important; 843 box-sizing: border-box !important; 844 max-width: 100% !important; 845 } 846 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow input::-webkit-input-placeholder, 847 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow input::-webkit-input-placeholder { color: #333333; } 848 849 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow input::-moz-placeholder, 850 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow input::-moz-placeholder { color: #333333; } 851 852 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow input:-ms-input-placeholder, 853 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow input:-ms-input-placeholder { color: #333333; } 854 855 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow input:-moz-placeholder, 856 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow input:-moz-placeholder { color: #333333; } 857 858 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow textarea, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow textarea { 859 background-color: #ffffff !important; 860 color: #333333 !important; 861 border-color: #cccccc; 862 border-radius: 4px !important; 863 border-style: solid !important; 864 border-width: 1px !important; 865 font-family: 'Open Sans', Arial, Helvetica, sans-serif; 866 font-size: 12px !important; 867 height: auto; 868 line-height: 21px !important; 869 margin-bottom: 0; 870 margin-top: 0; 871 padding: 10px 10px !important; 872 width: 100% !important; 873 box-sizing: border-box !important; 874 max-width: 100% !important; 875 } 876 877 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow .custom-radio .custom-control-label::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow .custom-radio .custom-control-label::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow .custom-checkbox .custom-control-label::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow .custom-checkbox .custom-control-label::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-embedPermissions .ml-form-embedPermissionsOptionsCheckbox .label-description::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-interestGroupsRow .ml-form-interestGroupsRowCheckbox .label-description::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-checkboxRow .label-description::before { 878 border-color: #cccccc!important; 879 background-color: #ffffff!important; 880 } 881 882 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow input.custom-control-input[type="checkbox"]{ 883 box-sizing: border-box; 884 padding: 0; 885 position: absolute; 886 z-index: -1; 887 opacity: 0; 888 margin-top: 5px; 889 margin-left: -1.5rem; 890 overflow: visible; 891 } 892 893 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow .custom-checkbox .custom-control-label::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow .custom-checkbox .custom-control-label::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-embedPermissions .ml-form-embedPermissionsOptionsCheckbox .label-description::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-interestGroupsRow .ml-form-interestGroupsRowCheckbox .label-description::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-checkboxRow .label-description::before { 894 border-radius: 4px!important; 895 } 896 897 898 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-checkboxRow input[type=checkbox]:checked~.label-description::after, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-embedPermissions .ml-form-embedPermissionsOptionsCheckbox input[type=checkbox]:checke
898d~.label-description::after, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow .custom-checkbox .custom-control-input:checked~.custom-control-label::after, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow .custom-checkbox .custom-control-input:checked~.custom-control-label::after, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-interestGroupsRow .ml-form-interestGroupsRowCheckbox input[type=checkbox]:checked~.label-description::after { 899 background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e"); 900 } 901 902 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow .custom-radio .custom-control-input:checked~.custom-control-label::after, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow .custom-radio .custom-control-input:checked~.custom-control-label::after { 903 background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e"); 904 } 905 906 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow .custom-radio .custom-control-input:checked~.custom-control-label::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow .custom-radio .custom-control-input:checked~.custom-control-label::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow .custom-checkbox .custom-control-input:checked~.custom-control-label::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow .custom-checkbox .custom-control-input:checked~.custom-control-label::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-embedPermissions .ml-form-embedPermissionsOptionsCheckbox input[type=checkbox]:checked~.label-description::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-interestGroupsRow .ml-form-interestGroupsRowCheckbox input[type=checkbox]:checked~.label-description::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-checkboxRow input[type=checkbox]:checked~.label-description::before { 907 border-color: #000000!important; 908 background-color: #000000!important; 909 } 910 911 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow .custom-radio .custom-control-label::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow .custom-radio .custom-control-label::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow .custom-radio .custom-control-label::after, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow .custom-radio .custom-control-label::after, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow .custom-checkbox .custom-control-label::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow .custom-checkbox .custom-control-label::after, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow .custom-checkbox .custom-control-label::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow .custom-checkbox .custom-control-label::after { 912 top: 2px; 913 box-sizing: border-box; 914 } 915 916 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-embedPermissions .ml-form-embedPermissionsOptionsCheckbox .label-description::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-embedPermissions .ml-form-embedPermissionsOptionsCheckbox .label-description::after, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-checkboxRow .label-description::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-checkboxRow .label-description::after { 917 top: 0px!important; 918 box-sizing: border-box!important; 919 } 920 921 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-checkboxRow .label-description::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-checkboxRow .label-description::after { 922 top: 0px!important; 923 box-sizing: border-box!important; 924 } 925 926 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-interestGroupsRow .ml-form-interestGroupsRowCheckbox .label-description::after { 927 top: 0px!important; 928 box-sizing: border-box!important; 929 position: absolute; 930 left: -1.5rem; 931 display: block; 932 width: 1rem; 933 height: 1rem; 934 content: ""; 935 } 936 937 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-interestGroupsRow .ml-form-interestGroupsRowCheckbox .label-description::before { 938 top: 0px!important; 939 box-sizing: border-box!important; 940 } 941 942 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .custom-control-label::before { 943 position: absolute; 944 top: 4px; 945 left: -1.5rem; 946 display: block; 947 width: 16px; 948 height: 16px; 949 pointer-events: none; 950 content: ""; 951 background-color: #ffffff; 952 border: #adb5bd solid 1px; 953 border-radius: 50%; 954 } 955 956 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .custom-control-label::after { 957 position: absolute; 958 top: 2px!important; 959 left: -1.5rem; 960 display: block; 961 width: 1rem; 962 height: 1rem; 963 content: ""; 964 } 965 966 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-embedPermissions .ml-form-embedPermissionsOptionsCheckbox .label-description::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-interestGroupsRow .ml-form-interestGroupsRowCheckbox .label-description::before, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-checkboxRow .label-description::before { 967 position: absolute; 968 top: 4px; 969 left: -1.5rem; 970 display: block; 971 width: 16px; 972 height: 16px; 973 pointer-events: none; 974 content: ""; 975 background-color: #ffffff; 976 border: #adb5bd solid 1px; 977 border-radius: 50%; 978 } 979 980 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-embedPermissions .ml-form-embedPermissionsOptionsCheckbox .label-description::after { 981 position: absolute; 982 top: 0px!important; 983 left: -1.5rem; 984 display: block; 985 width: 1rem; 986 height: 1rem; 987 content: ""; 988 } 989 990 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-checkboxRow .label-description::after { 991 position: absolute; 992 top: 0px!important; 993 left: -1.5rem; 994 display: block; 995 width: 1rem; 996 height: 1rem; 997 content: ""; 998 } 999 1000 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .custom-radio .custom-control-label::after { 1001 background: no-repeat 50%/50% 50%; 1002 } 1003 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .custom-checkbox .custom-control-label::after, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-embedPermissions .ml-form-embedPermissionsOptionsCheckbox .label-description::after, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-interestGroupsRow .ml-form-interestGroupsRowCheckbox .label-description::after, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-checkboxRow .label-description::after { 1004 background: no-repeat 50%/50% 50%; 1005 } 1006 1007 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow .custom-control, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow .custom-control { 1008 position: relative; 1009 display: block; 1010 min-height: 1.5rem; 1011 padding-left: 1.5rem; 1012 } 1013 1014 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow .custom-radio .custom-control-input, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow .custom-radio .custom-control-input, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow .custom-checkbox .custom-control-input, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow .custom-checkbox .custom-control-input { 1015 position: absolute; 1016 z-index: -1; 1017 opacity: 0; 1018 box-sizing: border-box; 1019 padding: 0; 1020 } 1021 1022 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow .custom-radio .custom-control-label, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow .custom-radio .custom-control-label, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow .custom-checkbox .custom-control-label, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow .custom-checkbox .custom-control-label { 1023 color: #000000; 1024 font-size: 12px!important; 1025 font-family: 'Open Sans', Arial, Helvetica, sans-serif; 1026 line-height: 22px; 1027 margin-bottom: 0; 1028 position: relative; 1029 vertical-align: top; 1030 font-style: normal; 1031 font-weight: 700; 1032 } 1033 1034 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-fieldRow .custom-select, #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow .custom-select { 1035 background-color: #ffffff !important; 1036 color: #333333 !important; 1037 border-color: #cccccc; 1038 border-radius: 4px !important; 1039 border-style: solid !important; 1040 border-width: 1px !important; 1041 font-family: 'Open Sans', Arial, Helvetica, sans-serif; 1042 font-size: 12px !important; 1043 line-height: 20px !important; 1044 margin-bottom: 0; 1045 margin-top: 0; 1046 padding: 10px 28px 10px 12px !important; 1047 width: 100% !important; 1048 box-sizing: border-box !important; 1049 max-width: 100% !important; 1050 height: auto; 1051 display: inline-block; 1052 vertical-align: middle; 1053 background: url('https://assets.mlcdn.com/ml/images/default/dropdown.svg') no-repeat right .75rem center/8px 10px; 1054 -webkit-appearance: none; 1055 -moz-appearance: none; 1056 appearance: none; 1057 } 1058 1059 1060 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow { 1061 height: auto; 1062 width: 100%; 1063 float: left; 1064 } 1065 .ml-form-formContent.horozintalForm .ml-form-horizontalRow .ml-input-horizontal { width: 70%; float: left; } 1066 .ml-form-formContent.horozintalForm .ml-form-horizontalRow .ml-button-horizontal { width: 30%; float: left; } 1067 .ml-form-formContent.horozintalForm .ml-form-horizontalRow .ml-button-horizontal.labelsOn { padding-top: 25px; } 1068 .ml-form-formContent.horozintalForm .ml-form-horizontalRow .horizontal-fields { box-sizing: border-box; float: left; padding-right: 10px; } 1069 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow input { 1070 background-color: #ffffff; 1071 color: #333333; 1072 border-color: #cccccc; 1073 border-radius: 4px; 1074 border-style: solid; 1075 border-width: 1px; 1076 font-family: 'Open Sans', Arial, Helvetica, sans-serif; 1077 font-size: 12px; 1078 line-height: 20px; 1079 margin-bottom: 0; 1080 margin-top: 0; 1081 padding: 10px 10px; 1082 width: 100%; 1083 box-sizing: border-box; 1084 overflow-y: initial; 1085 } 1086 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow button { 1087 background-color: #000000 !important; 1088 border-color: #000000; 1089 border-style: solid; 1090 border-width: 1px; 1091 border-radius: 4px; 1092 box-shadow: none; 1093 color: #ffffff !important; 1094 cursor: pointer; 1095 font-family: 'Raleway', sans-serif; 1096 font-size: 14px !important; 1097 font-weight: 700; 1098 line-height: 20px; 1099 margin: 0 !important; 1100 padding: 10px !important; 1101 width: 100%; 1102 height: auto; 1103 } 1104 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-horizontalRow button:hover { 1105 background-color: #333333 !important; 1106 border-color: #333333 !important; 1107 } 1108 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-checkboxRow input[type="checkbox"] { 1109 box-sizing: border-box; 1110 padding: 0; 1111 position: absolute; 1112 z-index: -1; 1113 opacity: 0; 1114 margin-top: 5px; 1115 margin-left: -1.5rem; 1116 overflow: visible; 1117 } 1118 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-checkboxRow .label-description { 1119 color: #000000; 1120 display: block; 1121 font-family: 'Open Sans', Arial, Helvetica, sans-serif; 1122 font-size: 12px; 1123 text-align: left; 1124 margin-bottom: 0; 1125 position: relative; 1126 vertical-align: top; 1127 } 1128 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-checkboxRow label { 1129 font-weight: normal; 1130 margin: 0; 1131 padding: 0; 1132 position: relative; 1133 display: block; 1134 min-height: 24px; 1135 padding-left: 24px; 1136 1137 } 1138 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-checkboxRow label a { 1139 color: #000000; 1140 text-decoration: underline; 1141 } 1142 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-checkboxRow label p { 1143 color: #000000 !important; 1144 font-family: 'Open Sans', Arial, Helvetica, sans-serif !important; 1145 font-size: 12px !important; 1146 font-weight: normal !important; 1147 line-height: 18px !important; 1148 padding: 0 !important; 1149 margin: 0 5px 0 0 !important; 1150 } 1151 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-checkboxRow label p:last-child { 1152 margin: 0; 1153 } 1154 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-embedSubmit { 1155 margin: 0 0 20px 0; 1156 float: left; 1157 width: 100%; 1158 } 1159 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-embedSubmit button { 1160 background-color: #000000 !important; 1161 border: none !important; 1162 border-radius: 4px !important; 1163 box-shadow: none !important; 1164 color: #ffffff !important; 1165 cursor: pointer; 1166 font-family: 'Raleway', sans-serif !important; 1167 font-size: 14px !important; 1168 font-weight: 700 !important; 1169 line-height: 21px !important; 1170 height: auto; 1171 padding: 10px !important; 1172 width: 100% !important; 1173 box-sizing: border-box !important; 1174 } 1175
1175 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-embedSubmit button.loading { 1176 display: none; 1177 } 1178 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-embedSubmit button:hover { 1179 background-color: #333333 !important; 1180 } 1181 .ml-subscribe-close { 1182 width: 30px; 1183 height: 30px; 1184 background: url('https://assets.mlcdn.com/ml/images/default/modal_close.png') no-repeat; 1185 background-size: 30px; 1186 cursor: pointer; 1187 margin-top: -10px; 1188 margin-right: -10px; 1189 position: absolute; 1190 top: 0; 1191 right: 0; 1192 } 1193 .ml-error input, .ml-error textarea, .ml-error select { 1194 border-color: red!important; 1195 } 1196 1197 .ml-error .custom-checkbox-radio-list { 1198 border: 1px solid red !important; 1199 border-radius: 19px; 1200 padding: 10px; 1201 } 1202 1203 .ml-error .label-description, 1204 .ml-error .label-description p, 1205 .ml-error .label-description p a, 1206 .ml-error label:first-child { 1207 color: #ff0000 !important; 1208 } 1209 1210 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-checkboxRow.ml-error .label-description p, 1211 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-checkboxRow.ml-error .label-description p:first-letter { 1212 color: #ff0000 !important; 1213 } 1214 @media only screen and (max-width: 900px){ 1215 1216 .ml-form-embedWrapper.embedDefault, .ml-form-embedWrapper.embedPopup { width: 100%!important; } 1217 .ml-form-formContent.horozintalForm { float: left!important; } 1218 .ml-form-formContent.horozintalForm .ml-form-horizontalRow { height: auto!important; width: 100%!important; float: left!important; } 1219 .ml-form-formContent.horozintalForm .ml-form-horizontalRow .ml-input-horizontal { width: 100%!important; } 1220 .ml-form-formContent.horozintalForm .ml-form-horizontalRow .ml-input-horizontal > div { padding-right: 0px!important; padding-bottom: 10px; } 1221 .ml-form-formContent.horozintalForm .ml-button-horizontal { width: 100%!important; } 1222 .ml-form-formContent.horozintalForm .ml-button-horizontal.labelsOn { padding-top: 0px!important; } 1223 1224 } 1225 </style> 1226 1227 <style type="text/css"> 1228 1229 .ml-mobileButton-horizontal { display: none; } 1230 1231 #mlb2-6731035 .ml-mobileButton-horizontal button { 1232 1233 background-color: #000000 !important; 1234 border-color: #000000 !important; 1235 border-style: solid !important; 1236 border-width: 1px !important; 1237 border-radius: 4px !important; 1238 box-shadow: none !important; 1239 color: #ffffff !important; 1240 cursor: pointer; 1241 font-family: 'Raleway', sans-serif !important; 1242 font-size: 14px !important; 1243 font-weight: 700 !important; 1244 line-height: 20px !important; 1245 padding: 10px !important; 1246 width: 100% !important; 1247 1248 } 1249 1250 @media only screen and (max-width: 900px) { 1251 #mlb2-6731035.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-form-formContent.horozintalForm { 1252 padding: 0 0 10px 0 !important; 1253 } 1254 .ml-hide-horizontal { display: none !important; } 1255 .ml-form-formContent.horozintalForm .ml-button-horizontal { display: none!important; } 1256 .ml-mobileButton-horizontal { display: inline-block !important; margin-bottom: 20px;width:100%; } 1257 .ml-form-formContent.horozintalForm .ml-form-horizontalRow .ml-input-horizontal > div { padding-bottom: 0px !important; } 1258 } 1259 1260 </style> 1261 <style type="text/css"> 1262 @media only screen and (max-width: 900px) { 1263 .ml-form-formContent.horozintalForm .ml-form-horizontalRow .horizontal-fields { 1264 margin-bottom: 10px !important; 1265 width: 100% !important; 1266 } 1267 } 1268 </style> 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 <div id="mlb2-6731035" class="ml-form-embedContainer ml-subscribe-form ml-subscribe-form-6731035"> 1430 <div class="ml-form-align-center "> 1431 <div class="ml-form-embedWrapper embedForm"> 1432 1433 1434 1435 1436 <div class="ml-form-embedBody ml-form-embedBodyHorizontal row-form"> 1437 1438 <div class="ml-form-embedContent" style=" "> 1439 1440 <h4 class="anchored"></h4> 1441 <p>Stay updated with the latest content</p> 1442 1443 </div> 1444 1445 <form class="ml-block-form" action="https://assets.mailerlite.com/jsonp/53633
14450/forms/95326166811936548/subscribe" data-code="" method="post" target="_blank"> 1446 1447 1448 <div class="ml-form-formContent horozintalForm"> 1449 <div class="ml-form-horizontalRow"> 1450 <div class="ml-input-horizontal"> 1451 1452 1453 <div style="width: 100%;" class="horizontal-fields"> 1454 1455 1456 1457 1458 1459 1460 <div class="ml-field-group ml-field-email ml-validate-email ml-validate-required"> 1461 1462 <!-- input --> 1463 <input type="email" class="form-control" data-inputmask="" name="fields[email]" placeholder="Email" autocomplete="email"> 1464 <!-- /input --> 1465 </div> 1466 1467 1468 1469 </div> 1470 1471 </div> 1472 1473 1474 <div class="ml-button-horizontal primary "> 1475 1476 <button type="submit" class="primary">Subscribe</button> 1477 1478 <button disabled="disabled" style="display: none;" type="button" class="loading"> 1479 <div class="ml-form-embedSubmitLoad"></div> 1480 <span class="sr-only">Loading...</span> 1481 </button> 1482 </div> 1483 </div> 1484 </div> 1485 1486 <!-- Privacy policy --> 1487 1488 <!-- /Privacy policy --> 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 <input type="hidden" name="ml-submit" value="1"> 1503 1504 1505 1506 <div class="ml-mobileButton-horizontal"> 1507 <button type="submit" class="primary">Subscribe</button> 1508 <button disabled="disabled" style="display: none;" type="button" class="loading"> 1509 <div class="ml-form-embedSubmitLoad"></div> 1510 <span class="sr-only">Loading...</span> 1511 </button> 1512 </div> 1513 <input type="hidden" name="anticsrf" value="true"> 1514 </form> 1515 </div> 1516 1517 <div class="ml-form-successBody row-success" style="display: none"> 1518 1519 <div class="ml-form-successContent"> 1520 1521 <h4 class="anchored">Thank you!</h4> 1522 <p>You have successfully joined the subscriber list.</p> 1523 1524 </div> 1525 1526 </div> 1527 </div> 1528 </div> 1529 </div> 1530 1531 1532 1533 1534 1535
1535<script> 1536 function ml_webform_success_6731035() { 1537 var $ = ml_jQuery || jQuery; 1538 $('.ml-subscribe-form-6731035 .row-success').show(); 1539 $('.ml-subscribe-form-6731035 .row-form').hide(); 1540 } 1541 </script>
1541 1542 1543 1544
1544<script src="https://groot.mailerlite.com/js/w/webforms.min.js?v1f25ee4b05f240a833e02c19975434a4" type="text/javascript"></script>
1544 1545
1545<script> 1546 fetch("https://assets.mailerlite.com/jsonp/536330/forms/95326166811936548/track-view") 1547 </script>
1547 1548 1549 1550 1551 1552</main> <!-- /main -->
1553<script id="quarto-html-after-body" type="application/javascript"> 1554 window.document.addEventListener("DOMContentLoaded", function (event) { 1555 const icon = "î§"; 1556 const anchorJS = new window.AnchorJS(); 1557 anchorJS.options = { 1558 placement: 'right', 1559 icon: icon 1560 }; 1561 anchorJS.add('.anchored'); 1562 const isCodeAnnotation = (el) => { 1563 for (const clz of el.classList) { 1564 if (clz.startsWith('code-annotation-')) { 1565 return true; 1566 } 1567 } 1568 return false; 1569 } 1570 const onCopySuccess = function(e) { 1571 // button target 1572 const button = e.trigger; 1573 // don't keep focus 1574 button.blur(); 1575 // flash "checked" 1576 button.classList.add('code-copy-button-checked'); 1577 var currentTitle = button.getAttribute("title"); 1578 button.setAttribute("title", "Copied!"); 1579 let tooltip; 1580 if (window.bootstrap) { 1581 button.setAttribute("data-bs-toggle", "tooltip"); 1582 button.setAttribute("data-bs-placement", "left"); 1583 button.setAttribute("data-bs-title", "Copied!"); 1584 tooltip = new bootstrap.Tooltip(button, 1585 { trigger: "manual", 1586 customClass: "code-copy-button-tooltip", 1587 offset: [0, -8]}); 1588 tooltip.show(); 1589 } 1590 setTimeout(function() { 1591 if (tooltip) { 1592 tooltip.hide(); 1593 button.removeAttribute("data-bs-title"); 1594 button.removeAttribute("data-bs-toggle"); 1595 button.removeAttribute("data-bs-placement"); 1596 } 1597 button.setAttribute("title", currentTitle); 1598 button.classList.remove('code-copy-button-checked'); 1599 }, 1000); 1600 // clear code selection 1601 e.clearSelection(); 1602 } 1603 const getTextToCopy = function(trigger) { 1604 const codeEl = trigger.previousElementSibling.cloneNode(true); 1605 for (const childEl of codeEl.children) { 1606 if (isCodeAnnotation(childEl)) { 1607 childEl.remove(); 1608 } 1609 } 1610 return codeEl.innerText; 1611 } 1612 const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', { 1613 text: getTextToCopy 1614 }); 1615 clipboard.on('success', onCopySuccess); 1616 if (window.document.getElementById('quarto-embedded-source-code-modal')) { 1617 const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', { 1618 text: getTextToCopy, 1619 container: window.document.getElementById('quarto-embedded-source-code-modal') 1620 }); 1621 clipboardModal.on('success', onCopySuccess); 1622 } 1623 var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//); 1624 var mailtoRegex = new RegExp(/^mailto:/); 1625 var filterRegex = new RegExp("https:\/\/xpsong\.com"); 1626 var isInternal = (href) => { 1627 return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href); 1628 } 1629 // Inspect non-navigation links and adorn them if external 1630 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)'); 1631 for (var i=0; i<links.length; i++) { 1632 const link = links[i]; 1633 if (!isInternal(link.href)) { 1634 // undo the damage that might have been done by quarto-nav.js in the case of 1635 // links that we want to consider external 1636 if (link.dataset.originalHref !== undefined) { 1637 link.href = link.dataset.originalHref; 1638 } 1639 } 1640 } 1641 function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) { 1642 const config = { 1643 allowHTML: true, 1644 maxWidth: 500, 1645 delay: 100, 1646 arrow: false, 1647 appendTo: function(el) { 1648 return el.parentElement; 1649 }, 1650 interactive: true, 1651 interactiveBorder: 10, 1652 theme: 'quarto', 1653 placement: 'bottom-start', 1654 }; 1655 if (contentFn) { 1656 config.content = contentFn; 1657 } 1658 if (onTriggerFn) { 1659 config.onTrigger = onTriggerFn; 1660 } 1661 if (onUntriggerFn) { 1662 config.onUntrigger = onUntriggerFn; 1663 } 1664 window.tippy(el, config); 1665 } 1666 const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]'); 1667 for (var i=0; i<noterefs.length; i++) { 1668 const ref = noterefs[i]; 1669 tippyHover(ref, function() { 1670 // use id or data attribute instead here 1671 let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href'); 1672 try { href = new URL(href).hash; } catch {} 1673 const id = href.replace(/^#\/?/, ""); 1674 const note = window.document.getElementById(id); 1675 if (note) { 1676 return note.innerHTML; 1677 } else { 1678 return ""; 1679 } 1680 }); 1681 } 1682 const xrefs = window.document.querySelectorAll('a.quarto-xref'); 1683 const processXRef = (id, note) => { 1684 // Strip column container classes 1685 const stripColumnClz = (el) => { 1686 el.classList.remove("page-full", "page-columns"); 1687 if (el.children) { 1688 for (const child of el.children) {
1689 stripColumnClz(child); 1690 } 1691 } 1692 } 1693 stripColumnClz(note) 1694 if (id === null || id.startsWith('sec-')) { 1695 // Special case sections, only their first couple elements 1696 const container = document.createElement("div"); 1697 if (note.children && note.children.length > 2) { 1698 container.appendChild(note.children[0].cloneNode(true)); 1699 for (let i = 1; i < note.children.length; i++) { 1700 const child = note.children[i]; 1701 if (child.tagName === "P" && child.innerText === "") { 1702 continue; 1703 } else { 1704 container.appendChild(child.cloneNode(true)); 1705 break; 1706 } 1707 } 1708 if (window.Quarto?.typesetMath) { 1709 window.Quarto.typesetMath(container); 1710 } 1711 return container.innerHTML 1712 } else { 1713 if (window.Quarto?.typesetMath) { 1714 window.Quarto.typesetMath(note); 1715 } 1716 return note.innerHTML; 1717 } 1718 } else { 1719 // Remove any anchor links if they are present 1720 const anchorLink = note.querySelector('a.anchorjs-link'); 1721 if (anchorLink) { 1722 anchorLink.remove(); 1723 } 1724 if (window.Quarto?.typesetMath) { 1725 window.Quarto.typesetMath(note); 1726 } 1727 if (note.classList.contains("callout")) { 1728 return note.outerHTML; 1729 } else { 1730 return note.innerHTML; 1731 } 1732 } 1733 } 1734 for (var i=0; i<xrefs.length; i++) { 1735 const xref = xrefs[i]; 1736 tippyHover(xref, undefined, function(instance) { 1737 instance.disable(); 1738 let url = xref.getAttribute('href'); 1739 let hash = undefined; 1740 if (url.startsWith('#')) { 1741 hash = url; 1742 } else { 1743 try { hash = new URL(url).hash; } catch {} 1744 } 1745 if (hash) { 1746 const id = hash.replace(/^#\/?/, ""); 1747 const note = window.document.getElementById(id); 1748 if (note !== null) { 1749 try { 1750 const html = processXRef(id, note.cloneNode(true)); 1751 instance.setContent(html); 1752 } finally { 1753 instance.enable(); 1754 instance.show(); 1755 } 1756 } else { 1757 // See if we can fetch this 1758 fetch(url.split('#')[0]) 1759 .then(res => res.text()) 1760 .then(html => { 1761 const parser = new DOMParser(); 1762 const htmlDoc = parser.parseFromString(html, "text/html"); 1763 const note = htmlDoc.getElementById(id); 1764 if (note !== null) { 1765 const html = processXRef(id, note); 1766 instance.setContent(html); 1767 } 1768 }).finally(() => { 1769 instance.enable(); 1770 instance.show(); 1771 }); 1772 } 1773 } else { 1774 // See if we can fetch a full url (with no hash to target) 1775 // This is a special case and we should probably do some content thinning / targeting 1776 fetch(url) 1777 .then(res => res.text()) 1778 .then(html => { 1779 const parser = new DOMParser(); 1780 const htmlDoc = parser.parseFromString(html, "text/html"); 1781 const note = htmlDoc.querySelector('main.content'); 1782 if (note !== null) { 1783 // This should only happen for chapter cross references 1784 // (since there is no id in the URL) 1785 // remove the first header 1786 if (note.children.length > 0 && note.children[0].tagName === "HEADER") { 1787 note.children[0].remove(); 1788 } 1789 const html = processXRef(null, note); 1790 instance.setContent(html); 1791 } 1792 }).finally(() => { 1793 instance.enable(); 1794 instance.show(); 1795 }); 1796 } 1797 }, function(instance) { 1798 }); 1799 } 1800 let selectedAnnoteEl; 1801 const selectorForAnnotation = ( cell, annotation) => { 1802 let cellAttr = 'data-code-cell="' + cell + '"'; 1803 let lineAttr = 'data-code-annotation="' + annotation + '"'; 1804 const selector = 'span[' + cellAttr + '][' + lineAttr + ']'; 1805 return selector; 1806 } 1807 const selectCodeLines = (annoteEl) => { 1808 const doc = window.document; 1809 const targetCell = annoteEl.getAttribute("data-target-cell"); 1810 const targetAnnotation = annoteEl.getAttribute("data-target-annotation"); 1811 const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation)); 1812 const lines = annoteSpan.getAttribute("data-code-lines").split(","); 1813 const lineIds = lines.map((line) => { 1814 return targetCell + "-" + line; 1815 }) 1816 let top = null; 1817 let height = null; 1818 let parent = null; 1819 if (lineIds.length > 0) { 1820 //compute the position of the single el (top and bottom and make a div) 1821 const el = window.document.getElementById(lineIds[0]); 1822 top = el.offsetTop; 1823 height = el.offsetHeight; 1824 parent = el.parentElement.parentElement; 1825 if (lineIds.length > 1) { 1826 const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]); 1827 const bottom = lastEl.offsetTop + lastEl.offsetHeight; 1828 height = bottom - top; 1829 } 1830 if (top !== null && height !== null && parent !== null) { 1831 // cook up a div (if necessary) and position it 1832 let div = window.document.getElementById("code-annotation-line-highlight"); 1833 if (div === null) { 1834 div = window.document.createElement("div"); 1835 div.setAttribute("id", "code-annotation-line-highlight"); 1836 div.style.position = 'absolute'; 1837 parent.appendChild(div); 1838 } 1839 div.style.top = top - 2 + "px"; 1840 div.style.height = height + 4 + "px"; 1841 div.style.left = 0; 1842 let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter"); 1843 if (gutterDiv === null) { 1844 gutterDiv = window.document.createElement("div"); 1845 gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter"); 1846 gutterDiv.style.position = 'absolute'; 1847 const codeCell = window.document.getElementById(targetCell); 1848 const gutter = codeCell.querySelector('.code-annotation-gutter'); 1849 gutter.appendChild(gutterDiv); 1850 } 1851 gutterDiv.style.top = top - 2 + "px"; 1852 gutterDiv.style.height = height + 4 + "px"; 1853 } 1854 selectedAnnoteEl = annoteEl; 1855 } 1856 }; 1857 const unselectCodeLines = () => { 1858 const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"]; 1859 elementsIds.forEach((elId) => { 1860 const div = window.document.getElementById(elId); 1861 if (div) { 1862 div.remove(); 1863 } 1864 }); 1865 selectedAnnoteEl = undefined; 1866 }; 1867 // Handle positioning of the toggle 1868 window.addEventListener( 1869 "resize", 1870 throttle(() => { 1871 elRect = undefined; 1872 if (selectedAnnoteEl) { 1873 selectCodeLines(selectedAnnoteEl); 1874 } 1875 }, 10) 1876 ); 1877 function throttle(fn, ms) { 1878 let throttle = false;
1879 let timer; 1880 return (...args) => { 1881 if(!throttle) { // first call gets through 1882 fn.apply(this, args); 1883 throttle = true; 1884 } else { // all the others get throttled 1885 if(timer) clearTimeout(timer); // cancel #2 1886 timer = setTimeout(() => { 1887 fn.apply(this, args); 1888 timer = throttle = false; 1889 }, ms); 1890 } 1891 }; 1892 } 1893 // Attach click handler to the DT 1894 const annoteDls = window.document.querySelectorAll('dt[data-target-cell]'); 1895 for (const annoteDlNode of annoteDls) { 1896 annoteDlNode.addEventListener('click', (event) => { 1897 const clickedEl = event.target; 1898 if (clickedEl !== selectedAnnoteEl) { 1899 unselectCodeLines(); 1900 const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active'); 1901 if (activeEl) { 1902 activeEl.classList.remove('code-annotation-active'); 1903 } 1904 selectCodeLines(clickedEl); 1905 clickedEl.classList.add('code-annotation-active'); 1906 } else { 1907 // Unselect the line 1908 unselectCodeLines(); 1909 clickedEl.classList.remove('code-annotation-active'); 1910 } 1911 }); 1912 } 1913 const findCites = (el) => { 1914 const parentEl = el.parentElement; 1915 if (parentEl) { 1916 const cites = parentEl.dataset.cites; 1917 if (cites) { 1918 return { 1919 el, 1920 cites: cites.split(' ') 1921 }; 1922 } else { 1923 return findCites(el.parentElement) 1924 } 1925 } else { 1926 return undefined; 1927 } 1928 }; 1929 var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]'); 1930 for (var i=0; i<bibliorefs.length; i++) { 1931 const ref = bibliorefs[i]; 1932 const citeInfo = findCites(ref); 1933 if (citeInfo) { 1934 tippyHover(citeInfo.el, function() { 1935 var popup = window.document.createElement('div'); 1936 citeInfo.cites.forEach(function(cite) { 1937 var citeDiv = window.document.createElement('div'); 1938 citeDiv.classList.add('hanging-indent'); 1939 citeDiv.classList.add('csl-entry'); 1940 var biblioDiv = window.document.getElementById('ref-' + cite); 1941 if (biblioDiv) { 1942 citeDiv.innerHTML = biblioDiv.innerHTML; 1943 } 1944 popup.appendChild(citeDiv); 1945 }); 1946 return popup.innerHTML; 1947 }); 1948 } 1949 } 1950 }); 1951 </script>
1951 1952</div> <!-- /content --> 1953<footer class="footer"> 1954 <div class="nav-footer"> 1955 <div class="nav-footer-left"> 1956<p>© 2026 XP Song. Built with <a href="https://quarto.org/">Quarto</a>.</p> 1957</div> 1958 <div class="nav-footer-center"> 1959 1960 </div> 1961 <div class="nav-footer-right"> 1962 <ul class="footer-items list-unstyled"> 1963 <li class="nav-item"> 1964 <a class="nav-link" href="mailto:[email protected]"> 1965<p>Contact</p> 1966</a> 1967 </li> 1968 <li class="nav-item"> 1969 <a class="nav-link" href="https://creativecommons.org/licenses/by-sa/4.0/"> 1970<p>License</p> 1971</a> 1972 </li> 1973 <li class="nav-item"> 1974 <a class="nav-link" href="./blog.xml"> 1975<p>RSS</p> 1976</a> 1977 </li> 1978</ul> 1979 </div> 1980 </div> 1981</footer> 1982 1983 1984 1985 1986</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.