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.8.26"> 6 7<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 8 9<meta name="author" content="Declan"> 10<meta name="dcterms.date" content="2024-12-09"> 11<meta name="description" content="Saving for a pension is rarely anyoneâs idea of a great time - but sometimes there are great incentives"> 12 13<title>Pictures of Pensions ð¼ï¸ â Calc with Dec ð§® ð¤</title> 14<style> 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/* CSS for syntax highlighting */ 27html { -webkit-text-size-adjust: 100%; } 28pre > code.sourceCode { white-space: pre; position: relative; } 29pre > code.sourceCode > span { display: inline-block; line-height: 1.25; } 30pre > code.sourceCode > span:empty { height: 1.2em; } 31.sourceCode { overflow: visible; } 32code.sourceCode > span { color: inherit; text-decoration: inherit; } 33div.sourceCode { margin: 1em 0; } 34pre.sourceCode { margin: 0; } 35@media screen { 36div.sourceCode { overflow: auto; } 37} 38@media print { 39pre > code.sourceCode { white-space: pre-wrap; } 40pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; } 41} 42pre.numberSource code 43 { counter-reset: source-line 0; } 44pre.numberSource code > span 45 { position: relative; left: -4em; counter-increment: source-line; } 46pre.numberSource code > span > a:first-child::before 47 { content: counter(source-line); 48 position: relative; left: -1em; text-align: right; vertical-align: baseline; 49 border: none; display: inline-block; 50 -webkit-touch-callout: none; -webkit-user-select: none; 51 -khtml-user-select: none; -moz-user-select: none; 52 -ms-user-select: none; user-select: none; 53 padding: 0 4px; width: 4em; 54 } 55pre.numberSource { margin-left: 3em; padding-left: 4px; } 56div.sourceCode 57 { } 58@media screen { 59pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; } 60} 61</style> 62 63
64<script src="../../site_libs/quarto-nav/quarto-nav.js"></script>
64 65<!-- DN removed headroom (less smooth scroll expe) -->
66<script src="../../site_libs/clipboard/clipboard.min.js"></script>
vendor: 1 bytes, line 66
66
67<script src="../../site_libs/quarto-search/autocomplete.umd.js"></script>
vendor: 1 bytes, line 67
67
68<script src="../../site_libs/quarto-search/fuse.min.js"></script>
vendor: 1 bytes, line 68
68
69<script src="../../site_libs/quarto-search/quarto-search.js"></script>
69 70<meta name="quarto:offset" content="../../">
71<script src="../../site_libs/quarto-html/quarto.js" type="module"></script>
vendor: 1 bytes, line 71
71
72<script src="../../site_libs/quarto-html/tabsets/tabsets.js" type="module"></script>
vendor: 1 bytes, line 72
72
73<script src="../../site_libs/quarto-html/axe/axe-check.js" type="module"></script>
vendor: 1 bytes, line 73
73
74<script src="../../site_libs/quarto-html/popper.min.js"></script>
vendor: 1 bytes, line 74
74
75<script src="../../site_libs/quarto-html/tippy.umd.min.js"></script>
vendor: 1 bytes, line 75
75
76<script src="../../site_libs/quarto-html/anchor.min.js"></script>
76 77<link href="../../site_libs/quarto-html/tippy.css" rel="stylesheet"> 78<link href="../../site_libs/quarto-html/quarto-syntax-highlighting-587c61ba64f3a5504c4d52d930310e48.css" rel="stylesheet" id="quarto-text-highlighting-styles">
79<script src="../../site_libs/bootstrap/bootstrap.min.js"></script>
79 80<link href="../../site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet"> 81<link href="../../site_libs/bootstrap/bootstrap-0df287d03f580c07ba6257b12f45a2a7.min.css" rel="stylesheet" append-hash="true" id="quarto-bootstrap" data-mode="light">
82<script src="../../site_libs/quarto-contrib/intersection-observer-polyfill-1.0.0/intersection-observer.js"></script>
vendor: 1 bytes, line 82
82
83<script src="../../site_libs/quarto-contrib/scrollama-3.2.0/scrollama.min.js"></script>
vendor: 1 bytes, line 83
83
84<script src="../../site_libs/quarto-contrib/closeread-0.1.0/closeread.js"></script>
vendor: 1 bytes, line 84
84
85<script id="quarto-search-options" type="application/json">{ 86 "location": "navbar", 87 "copy-button": false, 88 "collapse-after": 3, 89 "panel-placement": "end", 90 "type": "overlay", 91 "limit": 50, 92 "keyboard-shortcut": [ 93 "f", 94 "/", 95 "s" 96 ], 97 "show-item-context": false, 98 "language": { 99 "search-no-results-text": "No results", 100 "search-matching-documents-text": "matching documents", 101 "search-copy-link-title": "Copy link to search", 102 "search-hide-matches-text": "Hide additional matches", 103 "search-more-match-text": "more match in this document", 104 "search-more-matches-text": "more matches in this document", 105 "search-clear-button-title": "Clear", 106 "search-text-placeholder": "", 107 "search-detached-cancel-button-title": "Cancel", 108 "search-submit-button-title": "Submit", 109 "search-label": "Search" 110 } 111}</script>
vendor: 1 bytes, line 111
111
112<script type="module" src="../../site_libs/quarto-ojs/quarto-ojs-runtime.js"></script>
112 113<link href="../../site_libs/quarto-ojs/quarto-ojs.css" rel="stylesheet"> 114<link rel="stylesheet" href="../../resources/cookieconsent-2.9.1/dist/cookieconsent.css" media="print" onload="this.media='all'"> 115<meta cr-debug-mode="false"> 116<meta cr-remove-header-space="false"> 117 118 119<link rel="stylesheet" href="../../site_libs/quarto-contrib/quarto-project/qmd-lab/closeread/closeread.css"> 120<meta name="twitter:title" content="Pictures of Pensions ð¼ï¸ â Calc with Dec ð§® ð¤"> 121<meta name="twitter:description" content="Saving for a pension is rarely anyoneâs idea of a great time - but sometimes there are great incentives"> 122<meta name="twitter:image" content="https://calcwithdec.dev/posts/pictures-pensions/pensions-10-v-15-inflows2.png"> 123<meta name="twitter:image-height" content="165"> 124<meta name="twitter:image-width" content="339"> 125<meta name="twitter:card" content="summary_large_image"> 126</head> 127 128<body class="nav-fixed fullcontent quarto-light"> 129 130<div id="quarto-search-results"></div> 131 <header id="quarto-header" class="headroom fixed-top"> 132 <nav class="navbar navbar-expand-lg " data-bs-theme="dark"> 133 <div class="navbar-container container-fluid"> 134 <div class="navbar-brand-container mx-auto"> 135 <a class='navbar-brand' href='/'> 136 <span class="navbar-title">Calc with Dec ð§® ð¤</span> 137 </a> 138 </div> 139 <div id="quarto-search" class="" title="Search"></div> 140 <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(); }"> 141 <span class="navbar-toggler-icon"></span> 142</button> 143 <div class="collapse navbar-collapse" id="navbarCollapse"> 144 <ul class="navbar-nav navbar-nav-scroll ms-auto"> 145 <li class="nav-item"> 146 <a class='nav-link' href='/about'> 147<span class="menu-text">About Dec ð</span></a> 148 </li> 149 <li class="nav-item"> 150 <a class='nav-link' href='/'> 151<span class="menu-text">Blog ð</span></a> 152 </li> 153 <li class="nav-item"> 154 <a class='nav-link' href='/privacy'> 155<span class="menu-text">Privacy</span></a> 156 </li> 157 <li class="nav-item compact"> 158 <a class="nav-link" href="https://linkedin.com/in/declann"> <i class="bi bi-linkedin" role="img"> 159</i> 160<span class="menu-text"></span></a> 161 </li> 162 <li class="nav-item compact"> 163 <a class="nav-link" href="https://youtube.com/@calcwithdec"> <i class="bi bi-youtube" role="img"> 164</i> 165<span class="menu-text"></span></a> 166 </li> 167 <li class="nav-item compact"> 168 <a class="nav-link" href="https://twitter.com/calculang"> <i class="bi bi-twitter" role="img"> 169</i> 170<span class="menu-text"></span></a> 171 </li> 172 <li class="nav-item compact"> 173 <a class="nav-link" href="https://fosstodon.org/@calculang" rel="me"> <i class="bi bi-mastodon" role="img"> 174</i> 175<span class="menu-text"></span></a> 176 </li> 177</ul> 178 </div> <!-- /navcollapse --> 179 <div class="quarto-navbar-tools"> 180</div> 181 </div> <!-- /container-fluid --> 182 </nav> 183</header> 184<!-- content --> 185<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar"> 186<!-- sidebar --> 187<!-- margin-sidebar --> 188 189<!-- main --> 190<main class="content page-columns page-full" id="quarto-document-content"> 191 <!-- user-provided yaml closeread style options --> 192 <style> 193 :root { 194 --cr-section-background-color: transparent; 195--cr-narrative-background-color-sidebar: lightyellow; 196--cr-narrative-background-color-overlay: #111111dd; 197--cr-narrative-text-color-overlay: white; 198 } 199 </style> 200 201 202<header id="title-block-header" class="quarto-title-block default"> 203<div class="quarto-title"> 204<h1 class="title">Pictures of Pensions ð¼ï¸</h1> 205 <div class="quarto-categories"> 206 <div class="quarto-category">calculang</div> 207 <div class="quarto-category">actuarial</div> 208 <div class="quarto-category">visualization</div> 209 </div> 210 </div> 211 212<div> 213 <div class="description"> 214 Saving for a pension is rarely anyoneâs idea of a great time - but sometimes there are great incentives 215 </div> 216</div> 217 218 219<div class="quarto-title-meta"> 220 221 <div> 222 <div class="quarto-title-meta-heading">Author</div> 223 <div class="quarto-title-meta-contents"> 224 <p><a href='/about'>Declan</a> </p> 225 </div> 226 </div> 227 228 <div> 229 <div class="quarto-title-meta-heading">Published</div> 230 <div class="quarto-title-meta-contents"> 231 <p class="date">December 9, 2024</p> 232 </div> 233 </div> 234 235 236 </div> 237 238 239 240</header> 241 242 243<style> 244 245.description { 246 display: none 247} 248 249.narrative-col p { 250 font-family: math, monospace; 251 font-size: smaller; 252 text-align: justify; 253} 254 255.cell-hl { 256 border-radius: 4px; 257 padding: 1px 2px; 258 font-weight: bold; 259 text-wrap: nowrap; 260} 261 262.value { 263 background-color: lawngreen; 264} 265 266.cost { 267 background-color: crimson; 268 color: white; 269} 270 271.cr-section .narrative-col .trigger { 272 padding-inline: 5px !important; 273} 274 275</style> 276<p><em>With apologies to my pensions actuary friends</em>
276 - saving for a pension is rarely anyoneâs idea of a great time.</p> 277<p>But sometimes there are great <em>incentives</em>:</p> 278<ul> 279<li><strong>Employers might match your contributions</strong> - either because employment laws make them, or else because a good pension package helps to attract and retain talent (or both)</li> 280<li><strong>Governments might provide tax incentives</strong> - around the world populations are <a href="https://ourworldindata.org/age-structure">ageing</a>, and governments should prefer a financially independent retiring population</li> 281<li><strong>Compound returns</strong> - though certainly not guaranteed, compound returns can work like <em>magic</em> ⨠over a long pension savings horizon</li> 282</ul> 283<p>For as long as Iâve needed to think about pension savings, itâs helped me to draw a picture ð¼ï¸</p> 284<style> /* must keep outside of cr-section */ 285.m { 286 text-wrap: nowrap; 287} 288</style> 289<div class="cr-section column-body-outset cr-column-screen sidebar-left"> 290<div class="narrative-col"> 291<div class="trigger new-trigger" data-focus-on="cr-empty"> 292<div class="narrative"> 293<p>We want to visualize saving for a pension - with some nice incentives</p> 294</div> 295</div> 296<div class="trigger new-trigger" data-focus-on="cr-pens"> 297<div class="narrative"> 298<p>Letâs suppose you save <span class="m"><strong>⬠1,000</strong></span> each year from <span style="text-wrap:nowrap"><strong>age 50</strong></span></p> 299</div> 300</div> 301<div class="trigger new-trigger" data-focus-on="cr-pens"> 302<div class="narrative"> 303<p>For retirement at <span style="text-wrap:nowrap"><strong>age 65</strong></span></p> 304</div> 305</div> 306<div class="trigger new-trigger" data-focus-on="cr-pens"> 307<div class="narrative"> 308<p>In the end you, youâll have saved <span class="m"><strong>⬠15,000</strong> ð</span></p> 309</div> 310</div> 311<div class="trigger new-trigger" data-focus-on="cr-pens"> 312<div class="narrative"> 313<p>But: we hope your savings will grow with <strong>compounding returns</strong></p> 314</div> 315</div> 316<div class="trigger new-trigger" data-focus-on="cr-pens"> 317<div class="narrative"> 318<div class="cell"> 319<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb1" data-startfrom="109" data-source-offset="0"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 108;"><span id="cb1-109"><a href="#cb1-109" aria-hidden="true" tabindex="-1"></a><span class="fu">md</span><span class="vs">`Assuming **</span><span class="sc">${</span>d3<span class="op">.</span><span class="fu">format</span>(<span class="st">'.1%'</span>)(unit_growth_rate_in)<span class="sc">}</span><span class="vs"> compound returns** each year`</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 320<div class="cell-output cell-output-display"> 321<div id="ojs-cell-1" data-nodetype="expression"> 322 323</div> 324</div> 325</div> 326</div> 327</div> 328<div class="trigger new-trigger" data-focus-on="cr-pens"> 329<div class="narrative"> 330<p>You may also get <strong>tax relief</strong> on the amounts you save: reducing the <strong>effective</strong> cost</p> 331</div> 332</div> 333<div class="trigger new-trigger" data-focus-on="cr-pens"> 334<div class="narrative"> 335<p><strong>In Ireland</strong> the value of tax relief depends on the amount of tax you pay: which in turn depends on how much you earn</p> 336</div> 337</div> 338<div class="trigger new-trigger" data-focus-on="cr-pens"> 339<div class="narrative"> 340<p>Here I include a tax relief allowance for an individual earning <span class="m"><strong>⬠<span><span id="ojs-element-id-1"></span></span></strong></span></p> 341</div> 342</div> 343<div class="trigger new-trigger" data-focus-on="cr-pens"> 344<div class="narrative"> 345<div class="cell"> 346<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb2" data-startfrom="122" data-source-offset="0"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 121;"><span id="cb2-122"><a href="#cb2-122" aria-hidden="true" tabindex="-1"></a><span class="co">// some reactive issue causing trigger to fail? moved @cr-pens to :::{focus-on="cr-pens"} but didn't help !</span></span> 347<span id="cb2-123"><a href="#cb2-123" aria-hidden="true" tabindex="-1"></a><span class="fu">md</span><span class="vs">`The tax relief is <span class="m">**⬠</span><span class="sc">${</span><span class="co">
347/*model.js.empee_contribution_tax_relief({...cursor__1, age_in: 60})*/</span><span class="dv">400</span><span class="sc">}</span><span class="vs">**</span> so that the <span class="cell-hl cost">effective cost</span> of saving <span class="m">**⬠1,000**</span> is just <span class="m">**⬠</span><span class="sc">${</span><span class="co">/*model.js.empee_contribution_cost({...cursor__1, age_in: 60})*/</span><span class="dv">600</span><span class="sc">}</span><span class="vs">**</span>`</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 348<div class="cell-output cell-output-display"> 349<div id="ojs-cell-2" data-nodetype="expression"> 350 351</div> 352</div> 353</div> 354</div> 355</div> 356<div class="trigger new-trigger" data-focus-on="cr-pens"> 357<div class="narrative"> 358<p>Now letâs suppose your employer <strong>matches 100% of your contributions</strong></p> 359</div> 360</div> 361<div class="trigger new-trigger" data-focus-on="cr-pens"> 362<div class="narrative"> 363<p>Then you benefit from <strong>more contributions and more compound returns</strong></p> 364</div> 365</div> 366<div class="trigger new-trigger" style="opacity:0" data-focus-on="cr-pens"> 367<div class="narrative"> 368 369</div> 370</div> 371<div class="trigger new-trigger" style="opacity:0" data-focus-on="cr-pens"> 372<div class="narrative"> 373 374</div> 375</div> 376<div class="trigger new-trigger" data-focus-on="cr-pens"> 377<div class="narrative"> 378<p>Now we can see that a little <span class="cell-hl cost">effective cost</span></p> 379</div> 380</div> 381<div class="trigger new-trigger" data-focus-on="cr-pens"> 382<div class="narrative"> 383<p>Can result in lots more <span class="cell-hl value">value</span></p> 384</div> 385</div> 386<div class="trigger new-trigger" data-focus-on="cr-pens"> 387<div class="narrative"> 388<p><strong>Compound returns, tax relief, and employer matching</strong> can be extremely valuable for pension savings.</p> 389<p style="margin-top:1em;"> 390But itâs hopeful to think that money will accumulate, untouched by <strong>charges</strong> ð¸ 391</p> 392</div> 393</div> 394<div class="trigger new-trigger" data-focus-on="cr-pens"> 395<div class="narrative"> 396<p>Suppose there is a <strong>5% charge on contributions</strong></p> 397</div> 398</div> 399<div class="trigger new-trigger" data-focus-on="cr-pens"> 400<div class="narrative"> 401<p>And a <strong>management charge of 1%</strong> - deducted from the savings balance each year</p> 402</div> 403</div> 404<div class="trigger new-trigger" data-focus-on="cr-pens"> 405<div class="narrative"> 406<p>Now we can interpret the value of our pension savings as the <strong>area</strong> under inflows ð° <strong>minus</strong> the area under outflows ð¸</p> 407</div> 408</div> 409<div class="trigger new-trigger" data-focus-on="cr-pens"> 410<div class="narrative"> 411<p>At this level of charges, we can still see a lot of value</p> 412<p style="margin-top:1em"> 413ðï¸ 414</p> 415</div> 416</div> 417<div class="trigger new-trigger" data-focus-on="cr-pens"> 418<div class="narrative"> 419<p>So far, we assumed saving starts at <span style="text-wrap:nowrap"><strong>age 50</strong></span>.</p> 420<p style="margin-top:1em;"> 421<strong>What if saving started earlier?</strong> ð¤ 422</p> 423</div> 424</div> 425<div class="trigger new-trigger" data-focus-on="cr-pens"> 426<div class="narrative"> 427<p>Over a longer period, the value of <strong>compound returns</strong> is more apparent â¨</p> 428</div> 429</div> 430<div class="trigger new-trigger" data-focus-on="cr-pens"> 431<div class="narrative"> 432<p>Here in fact, the value from the first <strong>10 years of saving</strong> is <strong>more than</strong> the value from the following <strong>15 years</strong></p> 433<!--<p style="margin-top:1em;">**Why?**</p>--> 434<p style="margin-top:1em;"> 435⨠436</p> 437</div> 438</div> 439<div class="trigger new-trigger" style="opacity:0" data-focus-on="cr-pens"> 440<div class="narrative"> 441 442</div> 443</div> 444<div class="trigger new-trigger" style="opacity:0" data-focus-on="cr-pens"> 445<div class="narrative"> 446 447</div> 448</div> 449<div class="trigger new-trigger" style="opacity:0" data-focus-on="cr-pens"> 450<div class="narrative"> 451 452</div> 453</div> 454<div class="trigger new-trigger" style="opacity:0" data-focus-on="cr-pens"> 455<div class="narrative"> 456 457</div> 458</div> 459</div> 460<div class="sticky-col"> 461<div class="sticky-col-stack"> 462<div id="cr-empty" class="sticky" style="opacity:0"> 463 464</div> 465<div id="cr-empty" class="sticky" style="opacity:0"> 466 467</div> 468<div id="cr-pens" class="sticky"> 469<div id="viz"> 470 471</div> 472<div class="cell"> 473<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb3" data-startfrom="217" data-source-offset="0"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 216;"><span id="cb3-217"><a href="#cb3-217" aria-hidden="true" tabindex="-1"></a><span class="co">//md`**${d3.format('.1%')(unit_growth_rate_in)}
473**`</span></span> 474<span id="cb3-218"><a href="#cb3-218" aria-hidden="true" tabindex="-1"></a><span class="co">//md`**${d3.format(',.0f')(salary_0_in)}** salary`</span></span> 475<span id="cb3-219"><a href="#cb3-219" aria-hidden="true" tabindex="-1"></a></span> 476<span id="cb3-220"><a href="#cb3-220" aria-hidden="true" tabindex="-1"></a><span class="co">// check_cfs_vs_fund_value is weakened as a check</span></span> 477<span id="cb3-221"><a href="#cb3-221" aria-hidden="true" tabindex="-1"></a>viz <span class="op">=</span> <span class="fu">embed</span>(<span class="st">'#viz'</span><span class="op">,</span>spec<span class="op">,</span> {<span class="dt">renderer</span><span class="op">:</span> <span class="st">'svg'</span><span class="op">,</span> <span class="dt">actions</span><span class="op">:</span><span class="kw">false</span><span class="op">,</span> <span class="dt">tooltip</span><span class="op">:</span><span class="kw">false</span>})<span class="op">;</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 478<div class="cell-output cell-output-display"> 479<div id="ojs-cell-3" data-nodetype="declaration"> 480 481</div> 482</div> 483</div> 484</div> 485</div> 486</div> 487</div> 488<div class="cell hidden"> 489<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb4" data-startfrom="234" data-source-offset="-29"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 233;"><span id="cb4-234"><a href="#cb4-234" aria-hidden="true" tabindex="-1"></a>progress <span class="op">=</span> crTriggerIndex<span class="op">+</span>crTriggerProgress<span class="op">-</span>(crTriggerProgress<span class="op">></span><span class="fl">0.999999</span><span class="op">?</span><span class="dv">1</span><span class="op">:</span><span class="dv">0</span>)<span class="op">+</span>(crTriggerProgress<span class="op"><</span><span class="fl">0.000001</span><span class="op">?</span><span class="dv">1</span><span class="op">:</span><span class="dv">0</span>)</span> 490<span id="cb4-235"><a href="#cb4-235" aria-hidden="true" tabindex="-1"></a></span> 491<span id="cb4-236"><a href="#cb4-236" aria-hidden="true" tabindex="-1"></a>o0 <span class="op">=</span> <span class="dv">1</span></span> 492<span id="cb4-237"><a href="#cb4-237" aria-hidden="true" tabindex="-1"></a></span> 493<span id="cb4-238"><a href="#cb4-238" aria-hidden="true" tabindex="-1"></a>age_1_in_scale <span class="op">=</span> d3<span class="op">.</span><span class="fu">scaleLinear</span>()<span class="op">.</span><span class="fu">domain</span>([o0<span class="op">+.</span><span class="dv">5</span><span class="op">,</span> o0<span class="op">+</span><span class="fl">1.5</span>])<span class="op">.</span><span class="fu">range</span>([<span class="dv">51</span><span class="op">,</span> <span class="dv">70</span>])<span class="op">.</span><span class="fu">clamp</span>(<span class="kw">true</span>)</span> 494<span id="cb4-239"><a href="#cb4-239" aria-hidden="true" tabindex="-1"></a>age_1_in <span class="op">=</span> <span class="bu">Math</span><span class="op">.</span><span class="fu">round</span>(<span class="fu">age_1_in_scale</span>(progress))</span> 495<span id="cb4-240"><a href="#cb4-240" aria-hidden="true" tabindex="-1"></a></span> 496<span id="cb4-241"><a href="#cb4-241" aria-hidden="true" tabindex="-1"></a>o1 <span class="op">=</span> <span class="dv">4</span></span> 497<span id="cb4-242"><a href="#cb4-242" aria-hidden="true" tabindex="-1"></a>unit_growth_rate_in_scale <span class="op">=</span> d3<span class="op">.</span><span class="fu">scaleLinear</span>()<span class="op">.</span><span class="fu">domain</span>([o1<span class="op">+.</span><span class="dv">4</span><span class="op">,</span> o1<span class="op">+</span><span class="fl">1.5</span>])<span class="op">.</span><span class="fu">range</span>([<span class="dv">0</span><span class="op">,</span> <span class="fl">0.06</span>])<span class="op">.</span><span class="fu">clamp</span>(<span class="kw">true</span>)</span> 498<span id="cb4-243"><a href="#cb4-243" aria-hidden="true" tabindex="-1"></a>unit_growth_rate_in <span class="op">=</span> <span class="fu">unit_growth_rate_in_scale</span>(progress)</span> 499<span id="cb4-244"><a href="#cb4-244" aria-hidden="true" tabindex="-1"></a></span> 500<span id="cb4-245"><a href="#cb4-245" aria-hidden="true" tabindex="-1"></a>o2 <span class="op">=</span> <span class="dv">7</span></span> 501<span id="cb4-246"><a href="#cb4-246" aria-hidden="true" tabindex="-1"></a>salary_0_in_scale <span class="op">=</span> d3<span class="op">.</span><span class="fu">scaleLinear</span>()<span class="op">.</span><span class="fu">domain</span>([o2<span class="op">+.</span><span class="dv">8</span><span class="op">,</span> o2<span class="op">+</span><span class="fl">1.5</span>])<span class="op">.</span><span class="fu">range</span>([<span class="dv">10000</span><span class="op">,</span> <span class="dv">50000</span>])<span class="op">.</span><span class="fu">clamp</span>(<span class="kw">true</span>)</span> 502<span id="cb4-247"><a href="#cb4-247" aria-hidden="true" tabindex="-1"></a>salary_0_in <span class="op">=</span> <span class="fu">salary_0_in_scale</span>(progress)</span> 503<span id="cb4-248"><a href="#cb4-248" aria-hidden="true" tabindex="-1"></a></span> 504<span id="cb4-249"><a href="#cb4-249" aria-hidden="true" tabindex="-1"></a>statey <span class="op">=</span> (progress <span class="op">></span> <span class="fl">10.4</span> <span class="op">&&</span> progress <span class="op"><</span> <span class="fl">13.5</span>) <span class="op">||</span> progress <span class="op">></span> <span class="fl">21.5</span> <span class="op">&&</span> progress <span class="op"><</span> <span class="fl">25.3</span></span> 505<span id="cb4-250"><a href="#cb4-250" aria-hidden="true" tabindex="-1"></a></span> 506<span id="cb4-251"><a href="#cb4-251" aria-hidden="true" tabindex="-1"></a>oflash <span class="op">=</span> <span class="dv">9</span></span> 507<span id="cb4-252"><a href="#cb4-252" aria-hidden="true" tabindex="-1"></a></span> 508<span id="cb4-253"><a href="#cb4-253" aria-hidden="true" tabindex="-1"></a>flash <span class="op">=</span> d3<span class="op">.</span><span class="fu">scaleLinear</span>()<span class="op">.</span><span class="fu">domain</span>([<span class="fl">0.2</span><span class="op">,</span><span class="dv">0</span>])<span class="op">.</span><span class="fu">range</span>([<span class="dv">0</span><span class="op">,</span><span class="dv">1</span>])<span class="op">.</span><span class="fu">clamp</span>(<span class="kw">true</span>)(<span class="bu">Math</span><span class="op">.</span><span class="fu">abs</span>(progress<span class="op">-</span><span class="fl">9.7</span>)) <span class="op">+</span> d3<span class="op">.</span><span class="fu">scaleLinear</span>()<span class="op">.</span><span class="fu">domain</span>([<span class="fl">0.2</span><span class="op">,</span><span class="dv">0</span>])<span class="op">.</span><span class="fu">range</span>([<span class="dv">0</span><span class="op">,</span><span class="dv">1</span>])<span class="op">.</span><span class="fu">clamp</span>(<span class="kw">true</span>)(<span class="bu">Math</span><span class="op">.</span><span class="fu">abs</span>(progress<span class="op">-</span><span class="fl">14.7</span>
508)) </span> 509<span id="cb4-254"><a href="#cb4-254" aria-hidden="true" tabindex="-1"></a></span> 510<span id="cb4-255"><a href="#cb4-255" aria-hidden="true" tabindex="-1"></a></span> 511<span id="cb4-256"><a href="#cb4-256" aria-hidden="true" tabindex="-1"></a>flashall <span class="op">=</span> d3<span class="op">.</span><span class="fu">scaleLinear</span>()<span class="op">.</span><span class="fu">domain</span>([<span class="fl">0.2</span><span class="op">,</span><span class="dv">0</span>])<span class="op">.</span><span class="fu">range</span>([<span class="dv">0</span><span class="op">,</span><span class="dv">1</span>])<span class="op">.</span><span class="fu">clamp</span>(<span class="kw">true</span>)(<span class="bu">Math</span><span class="op">.</span><span class="fu">abs</span>(progress<span class="op">-</span><span class="fl">15.7</span>)) <span class="op">+</span> d3<span class="op">.</span><span class="fu">scaleLinear</span>()<span class="op">.</span><span class="fu">domain</span>([<span class="fl">0.9</span><span class="op">,</span><span class="dv">0</span>])<span class="op">.</span><span class="fu">range</span>([<span class="dv">0</span><span class="op">,</span><span class="dv">2</span>])<span class="op">.</span><span class="fu">clamp</span>(<span class="kw">true</span>)(<span class="bu">Math</span><span class="op">.</span><span class="fu">abs</span>(progress<span class="op">-</span><span class="fl">20.3</span>)) <span class="op">+</span> d3<span class="op">.</span><span class="fu">scaleLinear</span>()<span class="op">.</span><span class="fu">domain</span>([<span class="fl">0.6</span><span class="op">,</span><span class="dv">0</span>])<span class="op">.</span><span class="fu">range</span>([<span class="dv">0</span><span class="op">,</span><span class="dv">1</span>])<span class="op">.</span><span class="fu">clamp</span>(<span class="kw">true</span>)(<span class="bu">Math</span><span class="op">.</span><span class="fu">abs</span>(progress<span class="op">-</span><span class="fl">26.8</span>)) <span class="op">+</span> (progress <span class="op">></span> <span class="fl">26.8</span> <span class="op">?</span> <span class="dv">10</span> <span class="op">:</span> <span class="dv">0</span>)</span> 512<span id="cb4-257"><a href="#cb4-257" aria-hidden="true" tabindex="-1"></a></span> 513<span id="cb4-258"><a href="#cb4-258" aria-hidden="true" tabindex="-1"></a>outflows_opacity <span class="op">=</span> d3<span class="op">.</span><span class="fu">scaleLinear</span>()<span class="op">.</span><span class="fu">domain</span>([<span class="fl">16.5</span><span class="op">,</span><span class="dv">17</span>])<span class="op">.</span><span class="fu">range</span>([<span class="dv">0</span><span class="op">,</span><span class="dv">1</span>])<span class="op">.</span><span class="fu">clamp</span>(<span class="kw">true</span>)(progress)</span> 514<span id="cb4-259"><a href="#cb4-259" aria-hidden="true" tabindex="-1"></a></span> 515<span id="cb4-260"><a href="#cb4-260" aria-hidden="true" tabindex="-1"></a>{</span> 516<span id="cb4-261"><a href="#cb4-261" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> (progress <span class="op">></span> <span class="dv">12</span>) {</span> 517<span id="cb4-262"><a href="#cb4-262" aria-hidden="true" tabindex="-1"></a> viz<span class="op">.</span><span class="at">view</span><span class="op">.</span><span class="fu">signal</span>(<span class="st">'ydomain_x'</span><span class="op">,</span> (progress <span class="op"><</span> <span class="dv">20</span> <span class="op">?</span> progress<span class="op">-</span><span class="dv">12</span> <span class="op">:</span> progress <span class="op">-</span> <span class="fl">23.9</span>))<span class="op">.</span><span class="fu">resize</span>()<span class="op">.</span><span class="fu">run</span>()<span class="op">;</span></span> 518<span id="cb4-263"><a href="#cb4-263" aria-hidden="true" tabindex="-1"></a><span class="co">//viz.view.signal('ydomain_override', [0,5000]).resize().run();</span></span> 519<span id="cb4-264"><a href="#cb4-264" aria-hidden="true" tabindex="-1"></a><span class="co">//console.log(viz.view.signal('ydomain'))</span></span> 520<span id="cb4-265"><a href="#cb4-265" aria-hidden="true" tabindex="-1"></a>}</span> 521<span id="cb4-266"><a href="#cb4-266" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 522<div class="cell-output cell-output-display hidden"> 523<div> 524<div id="ojs-cell-4-1" data-nodetype="declaration"> 525 526</div> 527</div> 528</div> 529<div class="cell-output cell-output-display hidden"> 530<div> 531<div id="ojs-cell-4-2" data-nodetype="declaration"> 532 533</div> 534</div> 535</div> 536<div class="cell-output cell-output-display hidden"> 537<div> 538<div id="ojs-cell-4-3" data-nodetype="declaration"> 539 540</div> 541</div> 542</div> 543<div class="cell-output cell-output-display hidden"> 544<div> 545<div id="ojs-cell-4-4" data-nodetype="declaration"> 546 547</div> 548</div> 549</div> 550<div class="cell-output cell-output-display hidden"> 551<div> 552<div id="ojs-cell-4-5" data-nodetype="declaration"> 553 554</div> 555</div> 556</div> 557<div class="cell-output cell-output-display hidden"> 558<div> 559<div id="ojs-cell-4-6" data-nodetype="declaration"> 560 561</div> 562</div> 563</div> 564<div class="cell-output cell-output-display hidden"> 565<div> 566<div id="ojs-cell-4-7" data-nodetype="declaration"> 567 568</div> 569</div> 570</div> 571<div class="cell-output cell-output-display hidden"> 572<div> 573<div id="ojs-cell-4-8" data-nodetype="declaration"> 574 575</div> 576</div> 577</div> 578<div class="cell-output cell-output-display hidden"> 579<div> 580<div id="ojs-cell-4-9" data-nodetype="declaration"> 581 582</div> 583</div> 584</div> 585<div class="cell-output cell-output-display hidden"> 586<div> 587<div id="ojs-cell-4-10" data-nodetype="declaration"> 588 589</div> 590</div> 591</div> 592<div class="cell-output cell-output-display hidden"> 593<div> 594<div id="ojs-cell-4-11" data-nodetype="declaration"> 595 596</div> 597</div> 598</div> 599<div class="cell-output cell-output-display hidden"> 600<div> 601<div id="ojs-cell-4-12" data-nodetype="declaration"> 602 603</div> 604</div> 605</div> 606<div class="cell-output cell-output-display hidden"> 607<div> 608<div id="ojs-cell-4-13" data-nodetype="declaration"> 609 610</div> 611</div> 612</div> 613<div class="cell-output cell-output-display hidden"> 614<div> 615<div id="ojs-cell-4-14" data-nodetype="declaration"> 616 617</div> 618</div> 619</div> 620<div class="cell-output cell-output-display hidden"> 621<div> 622<div id="ojs-cell-4-15" data-nodetype="declaration"> 623 624</div> 625</div> 626</div> 627<div class="cell-output cell-output-display hidden"> 628<div> 629<div id="ojs-cell-4-16" data-nodetype="expression"> 630 631</div> 632</div> 633</div> 634<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb5" data-startfrom="268" data-source-offset="-1481"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 267;"><span id="cb5-268"><a href="#cb5-268" aria-hidden="true" tabindex="-1"></a>viz<span class="op">.</span><span class="at">view</span><span class="op">.</span><span class="fu">signal</span>(<span class="st">'outflows_opacity'</span><span class="op">,</span> outflows_opacity)</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 635<div class="cell-output cell-output-display hidden"> 636<div> 637<div id="ojs-cell-4-17" data-nodetype="expression"> 638 639</div> 640</div> 641</div> 642<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb6" data-startfrom="269" data-source-offset="-1544"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 268;"><span id="cb6-269"><a href="#cb6-269" aria-hidden="true" tabindex="-1"></a>viz<span class="op">.</span><span class="at">view</span><span class="op">.</span><span class="fu">signal</span>(<span class="st">'flash'</span><span class="op">,</span> flash)</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 643<div class="cell-output cell-output-display hidden"> 644<div> 645<div id="ojs-cell-4-18" data-nodetype="expression"> 646 647</div> 648</div> 649</div> 650<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb7" data-startfrom="270" data-source-offset="-1585"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 269;"><span id="cb7-270"><a href="#cb7-270" aria-hidden="true" tabindex="-1"></a>viz<span class="op">.</span><span class="at">view</span><span class="op">.</span><span class="fu">signal</span>(<span class="st">'flashall'</span><span class="op">,</span> flashall)<span class="op">.</span><span class="fu">run</span>()<span class="op">;</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 651<div class="cell-output cell-output-display hidden"> 652<div> 653<div id="ojs-cell-4-19" data-nodetype="expression"> 654 655</div> 656</div> 657</div> 658<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb8" data-startfrom="274" data-source-offset="-1633"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 273;"><span id="cb8-274"><a href="#cb8-274" aria-hidden="true" tabindex="-1"></a>o3 <span class="op">=</span> <span class="dv">10</span></span> 659<span id="cb8-275"><a href="#cb8-275" aria-hidden="true" tabindex="-1"></a>emper_matching_rate_in_scale <span class="op">=</span> d3<span class="op">.</span><span class="fu">scaleLinear</span>()<span class="op">.</span><span class="fu">domain</span>([o3<span class="op">+.</span><span class="dv">5</span><span class="op">,</span> o3<span class="op">+</span><span class="fl">1.5</span>])<span class="op">.</span><span class="fu">range</span>([<span class="dv">0</span><span class="op">,</span> <span class="dv">1</span>])<span class="op">.</span><span class="fu">clamp</span>(<span class="kw">true</span>)</span> 660<span id="cb8-276"><a href="#cb8-276" aria-hidden="true" tabindex="-1"></a>emper_matching_rate_in <span class="op">=</span> <span class="fu">emper_matching_rate_in_scale</span>(progress)</span> 661<span id="cb8-277"><a href="#cb8-277" aria-hidden="true" tabindex="-1"></a></span> 662<span id="cb8-278"><a href="#cb8-278" aria-hidden="true" tabindex="-1"></a></span> 663<span id="cb8-279"><a href="#cb8-279" aria-hidden="true" tabindex="-1"></a>
663o4 <span class="op">=</span> <span class="dv">17</span></span> 664<span id="cb8-280"><a href="#cb8-280" aria-hidden="true" tabindex="-1"></a>contribution_charge_rate_in <span class="op">=</span> d3<span class="op">.</span><span class="fu">scaleLinear</span>()<span class="op">.</span><span class="fu">domain</span>([o4<span class="op">+.</span><span class="dv">5</span><span class="op">,</span> o4<span class="op">+</span><span class="fl">1.5</span>])<span class="op">.</span><span class="fu">range</span>([<span class="dv">0</span><span class="op">,</span> <span class="fl">0.05</span>])<span class="op">.</span><span class="fu">clamp</span>(<span class="kw">true</span>)(progress)</span> 665<span id="cb8-281"><a href="#cb8-281" aria-hidden="true" tabindex="-1"></a>management_charge_rate_in <span class="op">=</span> d3<span class="op">.</span><span class="fu">scaleLinear</span>()<span class="op">.</span><span class="fu">domain</span>([o4<span class="op">+</span><span class="fl">1.5</span><span class="op">,</span> o4<span class="op">+</span><span class="dv">2</span>])<span class="op">.</span><span class="fu">range</span>([<span class="dv">0</span><span class="op">,</span> <span class="fl">0.01</span>])<span class="op">.</span><span class="fu">clamp</span>(<span class="kw">true</span>)(progress)</span> 666<span id="cb8-282"><a href="#cb8-282" aria-hidden="true" tabindex="-1"></a>o5 <span class="op">=</span> <span class="dv">21</span></span> 667<span id="cb8-283"><a href="#cb8-283" aria-hidden="true" tabindex="-1"></a>age_0_in <span class="op">=</span> <span class="bu">Math</span><span class="op">.</span><span class="fu">round</span>(d3<span class="op">.</span><span class="fu">scaleLinear</span>()<span class="op">.</span><span class="fu">domain</span>([o5<span class="op">+</span><span class="fl">0.7</span><span class="op">,</span> o5<span class="op">+</span><span class="fl">1.5</span>])<span class="op">.</span><span class="fu">range</span>([<span class="dv">50</span><span class="op">,</span><span class="dv">40</span>])<span class="op">.</span><span class="fu">clamp</span>(<span class="kw">true</span>)(progress))</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 668<div class="cell-output cell-output-display hidden"> 669<div> 670<div id="ojs-cell-4-20" data-nodetype="declaration"> 671 672</div> 673</div> 674</div> 675<div class="cell-output cell-output-display hidden"> 676<div> 677<div id="ojs-cell-4-21" data-nodetype="declaration"> 678 679</div> 680</div> 681</div> 682<div class="cell-output cell-output-display hidden"> 683<div> 684<div id="ojs-cell-4-22" data-nodetype="declaration"> 685 686</div> 687</div> 688</div> 689<div class="cell-output cell-output-display hidden"> 690<div> 691<div id="ojs-cell-4-23" data-nodetype="declaration"> 692 693</div> 694</div> 695</div> 696<div class="cell-output cell-output-display hidden"> 697<div> 698<div id="ojs-cell-4-24" data-nodetype="declaration"> 699 700</div> 701</div> 702</div> 703<div class="cell-output cell-output-display hidden"> 704<div> 705<div id="ojs-cell-4-25" data-nodetype="declaration"> 706 707</div> 708</div> 709</div> 710<div class="cell-output cell-output-display hidden"> 711<div> 712<div id="ojs-cell-4-26" data-nodetype="declaration"> 713 714</div> 715</div> 716</div> 717<div class="cell-output cell-output-display hidden"> 718<div> 719<div id="ojs-cell-4-27" data-nodetype="declaration"> 720 721</div> 722</div> 723</div> 724</div> 725<div style="margin-top: 2em;"> 726<section id="health-warnings" class="level3"> 727<h3 class="anchored" data-anchor-id="health-warnings">Health Warnings â ï¸</h3> 728<ul> 729<li><p>This <strong>illustrated pension savings projection</strong> includes features that may be valuable, but they are not applicable to everyone</p></li> 730<li><p>I used a <strong>6% compound returns assumption</strong>, but thereâs <em>no such thing</em> as guaranteed outcomes at rates such as 6%.<br>In a separate post: <a href='/posts/viz-risk/'><strong>Visualizing Risk</strong></a>, I illustrate a wider set of outcomes.</p></li> 731<li><p>Even when there is tax relief to <strong>save</strong> for a pension, this doesnât mean that there arenât taxes on pension income <strong>after retirement</strong><a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a></p></li> 732<li><p>There are usually additional rules about how pension savings can be used after retirement</p></li> 733</ul> 734<p>In other words: for help to understand pensions-related issues you should speak to a financial advisor who can understand your particular circumstances and communicate suitable choices. This blog post <em>isnât financial advice</em> â ï¸</p> 735<p><br></p> 736</section> 737<section id="formulas-and-custom-projections" class="level3"> 738<h3 class="anchored" data-anchor-id="formulas-and-custom-projections">formulas and custom projections ð</h3> 739<p>I use <a href="https://calculang.dev">calculang</a>: a language for calculations, to describe the pensions calculator and income tax calculations used here.</p> 740<p>You can explore more <strong>visual pension savings projections</strong> - and their formulas, using the draft <a href="https://calculang.dev/examples-viewer?id=pension-calculator">pension calculator example</a> on <a href="https://calculang.dev">calculang.dev</a></p> 741<div class="callout callout-style-simple callout-tip" color="green"> 742<div class="callout-body d-flex"> 743<div class="callout-icon-container"> 744<i class="callout-icon"></i> 745</div> 746<div class="callout-body-container"> 747<p>This blog post <a href='/'>and others</a> are an exploration applying <em>many tools available</em> to understand, interpret and communicate about models and numbers: tools including visualization, <a href='/posts/you-draw-inflation/'>interaction</a>, <a href='/posts/actuarial-terms-i/#reserves'>animated transitions</a>, and <a href='/posts/viz-risk/'>guided scroll-based interaction</a>.</p> 748</div> 749</div> 750</div> 751</section> 752</div> 753<div class="counter" style="display:none;position: fixed; top: 100px; right: 10px; background-color: skyblue; border-radius: 5px; padding: 18px 18px 0 18px; line-height: .8em; font-size: 0.7em; opacity:0.25"> 754<div class="cell"> 755<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb9" data-startfrom="327" data-source-offset="-31"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 326;"><span id="cb9-327"><a href="#cb9-327" aria-hidden="true" tabindex="-1"></a><span class="fu">md</span><span class="vs">`Active sticky: </span><span class="sc">${</span>crActiveSticky<span class="sc">}</span><span class="vs">`</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 756<div class="cell-output cell-output-display"> 757<div> 758<div id="ojs-cell-5-1" data-nodetype="expression"> 759 760</div> 761</div> 762</div> 763<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb10" data-startfrom="328" data-source-offset="-68"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 327;"><span id="cb10-328"><a href="#cb10-328" aria-hidden="true" tabindex="-1"></a><span class="fu">md</span><span class="vs">
763`Active trigger: </span><span class="sc">${</span>crTriggerIndex<span class="sc">}</span><span class="vs">`</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 764<div class="cell-output cell-output-display"> 765<div> 766<div id="ojs-cell-5-2" data-nodetype="expression"> 767 768</div> 769</div> 770</div> 771<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb11" data-startfrom="329" data-source-offset="-106"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 328;"><span id="cb11-329"><a href="#cb11-329" aria-hidden="true" tabindex="-1"></a><span class="fu">md</span><span class="vs">`Trigger progress: </span><span class="sc">${</span>(crTriggerProgress <span class="op">*</span> <span class="dv">100</span>)<span class="op">.</span><span class="fu">toFixed</span>(<span class="dv">1</span>)<span class="sc">}</span><span class="vs">%`</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 772<div class="cell-output cell-output-display"> 773<div> 774<div id="ojs-cell-5-3" data-nodetype="expression"> 775 776</div> 777</div> 778</div> 779<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb12" data-startfrom="330" data-source-offset="-169"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 329;"><span id="cb12-330"><a href="#cb12-330" aria-hidden="true" tabindex="-1"></a><span class="fu">md</span><span class="vs">`Scroll direction: </span><span class="sc">${</span>crDirection<span class="sc">}</span><span class="vs">`</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 780<div class="cell-output cell-output-display"> 781<div> 782<div id="ojs-cell-5-4" data-nodetype="expression"> 783 784</div> 785</div> 786</div> 787<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb13" data-startfrom="331" data-source-offset="-206"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 330;"><span id="cb13-331"><a href="#cb13-331" aria-hidden="true" tabindex="-1"></a><span class="fu">md</span><span class="vs">`Progress Block progress: </span><span class="sc">${</span>(crProgressBlock <span class="op">*</span> <span class="dv">100</span>)<span class="op">.</span><span class="fu">toFixed</span>(<span class="dv">1</span>)<span class="sc">}</span><span class="vs">%`</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 788<div class="cell-output cell-output-display"> 789<div> 790<div id="ojs-cell-5-5" data-nodetype="expression"> 791 792</div> 793</div> 794</div> 795<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb14" data-startfrom="332" data-source-offset="-274"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 331;"><span id="cb14-332"><a href="#cb14-332" aria-hidden="true" tabindex="-1"></a><span class="fu">md</span><span class="vs">`-----`</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 796<div class="cell-output cell-output-display"> 797<div> 798<div id="ojs-cell-5-6" data-nodetype="expression"> 799 800</div> 801</div> 802</div> 803<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb15" data-startfrom="333" data-source-offset="-284"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 332;"><span id="cb15-333"><a href="#cb15-333" aria-hidden="true" tabindex="-1"></a><span class="fu">md</span><span class="vs">`salary_0 </span><span class="sc">${</span>salary_0_in<span class="sc">}</span><span class="vs">`</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 804<div class="cell-output cell-output-display"> 805<div> 806<div id="ojs-cell-5-7" data-nodetype="expression"> 807 808</div> 809</div> 810</div> 811</div> 812</div> 813<details> 814<summary style="font-size:0.5em; opacity: 0.1"> 815appendix 816</summary> 817<div class="cell"> 818<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb16" data-startfrom="341" data-source-offset="-0"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 340;"><span id="cb16-341"><a href="#cb16-341" aria-hidden="true" tabindex="-1"></a><span class="im">
818import</span> {spec <span class="im">as</span> spec_} <span class="im">from</span> <span class="st">'./spec.js'</span></span> 819<span id="cb16-342"><a href="#cb16-342" aria-hidden="true" tabindex="-1"></a></span> 820<span id="cb16-343"><a href="#cb16-343" aria-hidden="true" tabindex="-1"></a>spec <span class="op">=</span> <span class="fu">spec_</span>(width<span class="op">,</span> y)</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 821<div class="cell-output cell-output-display"> 822<div> 823<div id="ojs-cell-6-1" data-nodetype="declaration"> 824 825</div> 826</div> 827</div> 828<div class="cell-output cell-output-display"> 829<div> 830<div id="ojs-cell-6-2" data-nodetype="declaration"> 831 832</div> 833</div> 834</div> 835</div> 836<div class="cell"> 837<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb17" data-startfrom="346" data-source-offset="0"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 345;"><span id="cb17-346"><a href="#cb17-346" aria-hidden="true" tabindex="-1"></a>viz<span class="op">.</span><span class="at">view</span><span class="op">.</span><span class="fu">data</span>(<span class="st">'data'</span><span class="op">,</span> [<span class="op">...</span>data])<span class="op">.</span><span class="fu">resize</span>()<span class="op">.</span><span class="fu">run</span>()<span class="op">;</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 838<div class="cell-output cell-output-display"> 839<div id="ojs-cell-7" data-nodetype="expression"> 840 841</div> 842</div> 843</div> 844<div class="cell"> 845<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb18" data-startfrom="351" data-source-offset="0"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 350;"><span id="cb18-351"><a href="#cb18-351" aria-hidden="true" tabindex="-1"></a><span class="bu">window</span><span class="op">.</span><span class="fu">dispatchEvent</span>(<span class="kw">new</span> <span class="bu">Event</span>(<span class="st">'resize'</span>))<span class="op">;</span> <span class="co">// without this, my own focus-on blocks don't get triggered (for some reason only my ones - OJS Variables ones work)</span></span> 846<span id="cb18-352"><a href="#cb18-352" aria-hidden="true" tabindex="-1"></a><span class="co">// They work when I resize. So triggering this programmatically.</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 847<div class="cell-output cell-output-display"> 848<div id="ojs-cell-8" data-nodetype="expression"> 849 850</div> 851</div> 852</div> 853<div class="cell"> 854<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb19" data-startfrom="361" data-source-offset="-0"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 360;"><span id="cb19-361"><a href="#cb19-361" aria-hidden="true" tabindex="-1"></a>embed_ <span class="op">=</span> <span class="pp">require</span>(<span class="st">"vega-embed"</span>)</span> 855<span id="cb19-362"><a href="#cb19-362" aria-hidden="true" tabindex="-1"></a></span> 856<span id="cb19-363"><a href="#cb19-363" aria-hidden="true" tabindex="-1"></a>embed <span class="op">=</span> (a<span class="op">,</span>b<span class="op">,</span>options) <span class="kw">=></span> <span class="fu">embed_</span>(a<span class="op">,</span>b<span class="op">,</span> {<span class="dt">renderer</span><span class="op">:</span><span class="st">'svg'</span><span class="op">,</span> <span class="co">/*theme:'carbong10',*/</span> actions<span class="op">,</span> <span class="op">...</span>options})<span class="op">;</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 857<div class="cell-output cell-output-display"> 858<div> 859<div id="ojs-cell-9-1" data-nodetype="declaration"> 860 861</div> 862</div> 863</div> 864<div class="cell-output cell-output-display"> 865<div> 866<div id="ojs-cell-9-2" data-nodetype="declaration"> 867 868</div> 869</div> 870</div> 871</div> 872<div class="cell"> 873<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb20" data-startfrom="367" data-source-offset="0"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 366;"><span id="cb20-367"><a href="#cb20-367" aria-hidden="true" tabindex="-1"></a>viewof actions <span class="op">=</span> Inputs<span class="op">.</span><span class="fu">toggle</span>({<span class="dt">label</span><span class="op">:</span><span class="st">'vega-embed actions?'</span><span class="op">,</span> <span class="dt">value</span><span class="op">:</span> <span class="kw">
873false</span>})</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 874<div class="cell-output cell-output-display"> 875<div id="ojs-cell-10" data-nodetype="declaration"> 876 877</div> 878</div> 879</div> 880<div class="cell"> 881<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb21" data-startfrom="372" data-source-offset="-0"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 371;"><span id="cb21-372"><a href="#cb21-372" aria-hidden="true" tabindex="-1"></a>helpers <span class="op">=</span> <span class="im">import</span>(</span> 882<span id="cb21-373"><a href="#cb21-373" aria-hidden="true" tabindex="-1"></a> <span class="st">"https://cdn.jsdelivr.net/gh/declann/calculang-js-browser-dev@main/helpers.js"</span></span> 883<span id="cb21-374"><a href="#cb21-374" aria-hidden="true" tabindex="-1"></a>)</span> 884<span id="cb21-375"><a href="#cb21-375" aria-hidden="true" tabindex="-1"></a></span> 885<span id="cb21-376"><a href="#cb21-376" aria-hidden="true" tabindex="-1"></a>calculang <span class="op">=</span> <span class="im">import</span>(</span> 886<span id="cb21-377"><a href="#cb21-377" aria-hidden="true" tabindex="-1"></a> <span class="st">"https://cdn.jsdelivr.net/gh/calculang/calculang@all_cul/packages/standalone/index.js"</span></span> 887<span id="cb21-378"><a href="#cb21-378" aria-hidden="true" tabindex="-1"></a>)</span> 888<span id="cb21-379"><a href="#cb21-379" aria-hidden="true" tabindex="-1"></a></span> 889<span id="cb21-380"><a href="#cb21-380" aria-hidden="true" tabindex="-1"></a>pre_fetch <span class="op">=</span> (<span class="cf">await</span> <span class="im">import</span>(</span> 890<span id="cb21-381"><a href="#cb21-381" aria-hidden="true" tabindex="-1"></a> <span class="st">"https://cdn.jsdelivr.net/gh/calculang/calculang@all_cul/packages/standalone/pre_fetch.mjs"</span></span> 891<span id="cb21-382"><a href="#cb21-382" aria-hidden="true" tabindex="-1"></a>))<span class="op">.</span><span class="at">pre_fetch</span></span> 892<span id="cb21-383"><a href="#cb21-383" aria-hidden="true" tabindex="-1"></a></span> 893<span id="cb21-384"><a href="#cb21-384" aria-hidden="true" tabindex="-1"></a></span> 894<span id="cb21-385"><a href="#cb21-385" aria-hidden="true" tabindex="-1"></a>fs0 <span class="op">=</span> <span class="cf">await</span> <span class="fu">pre_fetch</span>({</span> 895<span id="cb21-386"><a href="#cb21-386" aria-hidden="true" tabindex="-1"></a> <span class="st">"entrypoint.cul.js"</span><span class="op">:</span> <span class="cf">await</span> <span class="fu">FileAttachment</span>(<span class="st">'./cul/pension-calculator-overrides.cul.js'</span>)<span class="op">.</span><span class="fu">text</span>()</span> 896<span id="cb21-387"><a href="#cb21-387" aria-hidden="true" tabindex="-1"></a>})</span> 897<span id="cb21-388"><a href="#cb21-388" aria-hidden="true" tabindex="-1"></a></span> 898<span id="cb21-389"><a href="#cb21-389" aria-hidden="true" tabindex="-1"></a>model <span class="op">=</span> <span class="cf">await</span> calculang<span class="op">.</span><span class="fu">compile</span>({<span class="dt">entrypoint</span><span class="op">:</span> <span class="st">'entrypoint.cul.js'</span><span class="op">,</span> <span class="dt">fs</span><span class="op">:</span> fs0})</span> 899<span id="cb21-390"><a href="#cb21-390" aria-hidden="true" tabindex="-1"></a><span class="bu">window</span><span class="op">.</span><span class="at">model</span> <span class="op">=</span> model</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 900<div class="cell-output cell-output-display"> 901<div> 902<div id="ojs-cell-11-1" data-nodetype="declaration"> 903 904</div> 905</div> 906</div> 907<div class="cell-output cell-output-display"> 908<div> 909<div id="ojs-cell-11-2" data-nodetype="declaration"> 910 911</div> 912</div> 913</div> 914<div class="cell-output cell-output-display"> 915<div> 916<div id="ojs-cell-11-3" data-nodetype="declaration"> 917 918</div> 919</div> 920</div> 921<div class="cell-output cell-output-display"> 922<div> 923<div id="ojs-cell-11-4" data-nodetype="declaration"> 924 925</div> 926</div> 927</div> 928<div class="cell-output cell-output-display"> 929<div> 930<div id="ojs-cell-11-5" data-nodetype="declaration"> 931 932</div> 933</div> 934</div> 935<div class="cell-output cell-output-display"> 936<div> 937<div id="ojs-cell-11-6" data-nodetype="expression"> 938 939</div> 940</div> 941</div> 942<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb22" data-startfrom="394" data-source-offset="-574"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 393;"><span id="cb22-394"><a href="#cb22-394" aria-hidden="true" tabindex="-1"></a>formulae <span class="op">=</span> [<span class="st">
942'empee_contribution_tax_relief'</span><span class="op">,</span> <span class="st">'empee_contribution_cost'</span><span class="op">,</span> <span class="st">'emper_contribution'</span><span class="op">,</span> <span class="st">'fund_growth'</span><span class="op">,</span> <span class="st">'contribution_charge'</span><span class="op">,</span> <span class="st">'management_charge'</span>]</span> 943<span id="cb22-395"><a href="#cb22-395" aria-hidden="true" tabindex="-1"></a></span> 944<span id="cb22-396"><a href="#cb22-396" aria-hidden="true" tabindex="-1"></a></span> 945<span id="cb22-397"><a href="#cb22-397" aria-hidden="true" tabindex="-1"></a>cursor_0 <span class="op">=</span> ({age_0_in<span class="op">,</span> <span class="dt">fund_value_0_in</span><span class="op">:</span><span class="dv">0</span><span class="op">,</span> <span class="dt">unit_growth_rate_in</span><span class="op">:</span><span class="dv">0</span><span class="op">,</span> <span class="dt">retirement_age_in</span><span class="op">:</span><span class="dv">65</span><span class="op">,</span> <span class="dt">missed_contribution_age_in</span><span class="op">:</span><span class="dv">15</span><span class="op">,</span> <span class="dt">salary_age_0_in</span><span class="op">:</span><span class="dv">50</span><span class="op">,</span> salary_0_in<span class="op">,</span> <span class="dt">salary_inflation_rate_in</span><span class="op">:</span><span class="dv">0</span><span class="op">,</span> <span class="co">/*empee_contribution_rate_in:.1 Moved to fixed contribution amount */</span>emper_matching_rate_in<span class="op">,</span> contribution_charge_rate_in<span class="op">,</span> management_charge_rate_in<span class="op">,</span> age_1_in})</span> 946<span id="cb22-398"><a href="#cb22-398" aria-hidden="true" tabindex="-1"></a></span> 947<span id="cb22-399"><a href="#cb22-399" aria-hidden="true" tabindex="-1"></a>cursor <span class="op">=</span> cursor_0</span> 948<span id="cb22-400"><a href="#cb22-400" aria-hidden="true" tabindex="-1"></a></span> 949<span id="cb22-401"><a href="#cb22-401" aria-hidden="true" tabindex="-1"></a>cursor_1 <span class="op">=</span> ({<span class="op">...</span>cursor<span class="op">,</span> unit_growth_rate_in})</span> 950<span id="cb22-402"><a href="#cb22-402" aria-hidden="true" tabindex="-1"></a></span> 951<span id="cb22-403"><a href="#cb22-403" aria-hidden="true" tabindex="-1"></a><span class="bu">window</span><span class="op">.</span><span class="at">cursor_0</span> <span class="op">=</span> cursor_0</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 952<div class="cell-output cell-output-display"> 953<div> 954<div id="ojs-cell-11-7" data-nodetype="declaration"> 955 956</div> 957</div> 958</div> 959<div class="cell-output cell-output-display"> 960<div> 961<div id="ojs-cell-11-8" data-nodetype="declaration"> 962 963</div> 964</div> 965</div> 966<div class="cell-output cell-output-display"> 967<div> 968<div id="ojs-cell-11-9" data-nodetype="declaration"> 969 970</div> 971</div> 972</div> 973<div class="cell-output cell-output-display"> 974<div> 975<div id="ojs-cell-11-10" data-nodetype="declaration"> 976 977</div> 978</div> 979</div> 980<div class="cell-output cell-output-display"> 981<div> 982<div id="ojs-cell-11-11" data-nodetype="expression"> 983 984</div> 985</div> 986</div> 987<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb23" data-startfrom="404" data-source-offset="-1162"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 403;"><span id="cb23-404"><a href="#cb23-404" aria-hidden="true" tabindex="-1"></a><span class="bu">window</span><span class="op">.</span><span class="at">cursor</span> <span class="op">=</span> cursor_1</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 988<div class="cell-output cell-output-display"> 989<div> 990<div id="ojs-cell-11-12" data-nodetype="expression"> 991 992</div> 993</div> 994</div> 995<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb24" data-startfrom="407" data-source-offset="-1241"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 406;"><span id="cb24-407"><a href="#cb24-407" aria-hidden="true" tabindex="-1"></a>viz<span class="op">.</span><span class="at">view</span><span class="op">.</span><span class="fu">signal</span>(<span class="st">'statey'</span><span class="op">,</span> statey)<span class="op">.</span><span class="fu">run</span>()</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 996<div class="cell-output cell-output-display"> 997<div> 998<div id="ojs-cell-11-13" data-nodetype="expression"> 999 1000</div> 1001</div> 1002</div> 1003<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb25" data-startfrom="410" data-source-offset="-1348"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 409;"><span id="cb25-410"><a href="#cb25-410" aria-hidden="true" tabindex="-1"></a>cursor__0 <span class="op">=</span> {</span> 1004<span id="cb25-411"><a href="#cb25-411" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> (progress <span class="op"><</span> <span class="dv">17</span>) <span class="cf">return</span> ({<span class="op">...</span>cursor_1<span class="op">,</span><span class="dt">emper_matching_rate_in</span><span class="op">:</span><span class="dv">0</span>})</span> 1005<span id="cb25-412"><a href="#cb25-412" aria-hidden="true" tabindex="-1"></a> <span class="cf">else</span> <span class="cf">if</span> (progress <span class="op"><</span> <span class="dv">21</span>) <span class="cf">return</span> ({<span class="op">...</span>cursor_1<span class="op">,</span> <span class="dt">management_charge_rate_in</span><span class="op">:</span><span class="dv">0</span><span class="op">,</span> <span class="dt">contribution_charge_rate_in</span><span class="op">:</span><span class="dv">0</span>})</span> 1006<span id="cb25-413"><a href="#cb25-413" aria-hidden="true" tabindex="-1"></a> <span class="cf">else</span> <span class="cf">return</span> ({<span class="op">...</span>cursor_1<span class="op">,</span> <span class="dt">age_0_in</span><span class="op">:</span><span class="dv">50</span>})</span> 1007<span id="cb25-414"><a href="#cb25-414" aria-hidden="true" tabindex="-1"></a>}</span> 1008<span id="cb25-415"><a href="#cb25-415" aria-hidden="true" tabindex="-1"></a></span> 1009<span id="cb25-416"><a href="#cb25-416" aria-hidden="true" tabindex="-1"></a>cursor__1 <span class="op">=</span> {</span> 1010<span id="cb25-417"><a href="#cb25-417" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> cursor_1</span> 1011<span id="cb25-418"><a href="#cb25-418" aria-hidden="true" tabindex="-1"></a>}</span> 1012<span id="cb25-419"><a href="#cb25-419" aria-hidden="true" tabindex="-1"></a></span> 1013<span id="cb25-420"><a href="#cb25-420" aria-hidden="true" tabindex="-1"></a>data <span class="op">=</span> helpers<span class="op">.</span><span class="fu">calcudata</span>({</span> 1014<span id="cb25-421"><a href="#cb25-421" aria-hidden="true" tabindex="-1"></a> <span class="dt">models</span><span class="op">:</span> [model<span class="op">.</span><span class="at">js</span>]<span class="op">,</span></span> 1015<span id="cb25-422"><a href="#cb25-422" aria-hidden="true" tabindex="-1"></a> <span class="dt">input_domains</span><span class="op">:</span> {<span class="dt">age_in</span><span class="op">:</span> _<span class="op">.</span><span class="fu">range</span>(cursor<span class="op">.</span><span class="at">age_0_in</span><span class="op">,</span>cursor<span class="op">.</span><span class="at">retirement_age_in</span>)}<span class="op">,</span></span> 1016<span id="cb25-423"><a href="#cb25-423" aria-hidden="true" tabindex="-1"></a> <span class="dt">input_cursors</span><span class="op">:</span> [cursor__0<span class="op">,</span> cursor__1]<span class="op">,</span></span> 1017<span id="cb25-424"><a href="#cb25-424" aria-hidden="true" tabindex="-1"></a> <span class="dt">outputs</span><span class="op">:</span> [<span class="op">...</span>formulae<span class="op">,</span> <span class="st">
1017'check_cfs_vs_fund_value'</span>]<span class="op">,</span></span> 1018<span id="cb25-425"><a href="#cb25-425" aria-hidden="true" tabindex="-1"></a> <span class="dt">pivot</span><span class="op">:</span> <span class="kw">false</span></span> 1019<span id="cb25-426"><a href="#cb25-426" aria-hidden="true" tabindex="-1"></a>})</span> 1020<span id="cb25-427"><a href="#cb25-427" aria-hidden="true" tabindex="-1"></a></span> 1021<span id="cb25-428"><a href="#cb25-428" aria-hidden="true" tabindex="-1"></a>viewof shared_y_scale <span class="op">=</span> Inputs<span class="op">.</span><span class="fu">toggle</span>({<span class="dt">label</span><span class="op">:</span> <span class="st">'shared y scale?'</span><span class="op">,</span> <span class="dt">value</span><span class="op">:</span> <span class="kw">true</span>})</span> 1022<span id="cb25-429"><a href="#cb25-429" aria-hidden="true" tabindex="-1"></a></span> 1023<span id="cb25-430"><a href="#cb25-430" aria-hidden="true" tabindex="-1"></a></span> 1024<span id="cb25-431"><a href="#cb25-431" aria-hidden="true" tabindex="-1"></a>y <span class="op">=</span> shared_y_scale <span class="op">?</span> <span class="st">'y_shared'</span> <span class="op">:</span> <span class="st">'y'</span></span> 1025<span id="cb25-432"><a href="#cb25-432" aria-hidden="true" tabindex="-1"></a></span> 1026<span id="cb25-433"><a href="#cb25-433" aria-hidden="true" tabindex="-1"></a>f <span class="op">=</span> d3<span class="op">.</span><span class="fu">format</span>(<span class="st">',.2f'</span>)</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 1027<div class="cell-output cell-output-display"> 1028<div> 1029<div id="ojs-cell-11-14" data-nodetype="declaration"> 1030 1031</div> 1032</div> 1033</div> 1034<div class="cell-output cell-output-display"> 1035<div> 1036<div id="ojs-cell-11-15" data-nodetype="declaration"> 1037 1038</div> 1039</div> 1040</div> 1041<div class="cell-output cell-output-display"> 1042<div> 1043<div id="ojs-cell-11-16" data-nodetype="declaration"> 1044 1045</div> 1046</div> 1047</div> 1048<div class="cell-output cell-output-display"> 1049<div> 1050<div id="ojs-cell-11-17" data-nodetype="declaration"> 1051 1052</div> 1053</div> 1054</div> 1055<div class="cell-output cell-output-display"> 1056<div> 1057<div id="ojs-cell-11-18" data-nodetype="declaration"> 1058 1059</div> 1060</div> 1061</div> 1062<div class="cell-output cell-output-display"> 1063<div> 1064<div id="ojs-cell-11-19" data-nodetype="declaration"> 1065 1066</div> 1067</div> 1068</div> 1069</div> 1070<div class="cell"> 1071<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb26" data-startfrom="437" data-source-offset="0"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 436;"><span id="cb26-437"><a href="#cb26-437" aria-hidden="true" tabindex="-1"></a><span class="co">// I need ojs blocks to be inside focus-on blocks, or they break a trigger</span></span> 1072<span id="cb26-438"><a href="#cb26-438" aria-hidden="true" tabindex="-1"></a>e <span class="op">=</span> d3<span class="op">.</span><span class="fu">sum</span>(data<span class="op">.</span><span class="fu">filter</span>(d <span class="kw">=></span> d<span class="op">.</span><span class="at">input_cursor_id</span> <span class="op">==</span> <span class="dv">1</span> <span class="op">&&</span> d<span class="op">.</span><span class="at">formula</span> <span class="op">==</span><span class="st">"empee_contribution_cost"</span>)<span class="op">,</span> d <span class="kw">=></span> d<span class="op">.</span><span class="at">value</span>)</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 1073<div class="cell-output cell-output-display"> 1074<div id="ojs-cell-12" data-nodetype="declaration"> 1075 1076</div> 1077</div> 1078</div> 1079<div class="cell"> 1080<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb27" data-startfrom="444" data-source-offset="0"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 443;"><span id="cb27-444"><a href="#cb27-444" aria-hidden="true" tabindex="-1"></a>{</span> 1081<span id="cb27-445"><a href="#cb27-445" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> (<span class="kw">const</span> el <span class="kw">of</span> <span class="bu">document</span><span class="op">.</span><span class="fu">getElementsByClassName</span>(<span class="st">'cr-column-screen'</span>)) {</span> 1082<span id="cb27-446"><a href="#cb27-446" aria-hidden="true" tabindex="-1"></a> el<span class="op">.</span><span class="at">classList</span><span class="op">.</span><span class="fu">remove</span>(<span class="st">'cr-column-screen'</span>)</span> 1083<span id="cb27-447"><a href="#cb27-447" aria-hidden="true" tabindex="-1"></a>}</span> 1084<span id="cb27-448"><a href="#cb27-448" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 1085<div class="cell-output cell-output-display"> 1086<div id="ojs-cell-13" data-nodetype="expression"> 1087 1088</div> 1089</div> 1090</div> 1091<div class="cell"> 1092<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb28" data-startfrom="455" data-source-offset="-35"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 454;"><span id="cb28-455"><a href="#cb28-455" aria-hidden="true" tabindex="-1"></a>mutable progress5 <span class="op">=</span> <span class="kw">
1092false</span><span class="op">;</span></span> 1093<span id="cb28-456"><a href="#cb28-456" aria-hidden="true" tabindex="-1"></a> mutable progress10 <span class="op">=</span> <span class="kw">false</span><span class="op">;</span></span> 1094<span id="cb28-457"><a href="#cb28-457" aria-hidden="true" tabindex="-1"></a> mutable progress15 <span class="op">=</span> <span class="kw">false</span><span class="op">;</span></span> 1095<span id="cb28-458"><a href="#cb28-458" aria-hidden="true" tabindex="-1"></a> mutable progress20 <span class="op">=</span> <span class="kw">false</span><span class="op">;</span></span> 1096<span id="cb28-459"><a href="#cb28-459" aria-hidden="true" tabindex="-1"></a> mutable progress25 <span class="op">=</span> <span class="kw">false</span><span class="op">;</span></span> 1097<span id="cb28-460"><a href="#cb28-460" aria-hidden="true" tabindex="-1"></a> mutable progress30 <span class="op">=</span> <span class="kw">false</span><span class="op">;</span></span> 1098<span id="cb28-461"><a href="#cb28-461" aria-hidden="true" tabindex="-1"></a></span> 1099<span id="cb28-462"><a href="#cb28-462" aria-hidden="true" tabindex="-1"></a>{</span> 1100<span id="cb28-463"><a href="#cb28-463" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> (<span class="bu">window</span><span class="op">.</span><span class="at">plausible</span>) {</span> 1101<span id="cb28-464"><a href="#cb28-464" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> (progress <span class="op">></span> <span class="dv">5</span> <span class="op">&&</span> <span class="op">!</span>progress5) {</span> 1102<span id="cb28-465"><a href="#cb28-465" aria-hidden="true" tabindex="-1"></a> mutable progress5 <span class="op">=</span> <span class="kw">true</span><span class="op">;</span></span> 1103<span id="cb28-466"><a href="#cb28-466" aria-hidden="true" tabindex="-1"></a>
1103 <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="st">'hit 5'</span>)</span> 1104<span id="cb28-467"><a href="#cb28-467" aria-hidden="true" tabindex="-1"></a> <span class="bu">window</span><span class="op">.</span><span class="fu">plausible</span>(<span class="st">'pictures-pensions progress'</span><span class="op">,</span> { <span class="dt">props</span><span class="op">:</span> {<span class="dt">index</span><span class="op">:</span> <span class="dv">5</span>}})</span> 1105<span id="cb28-468"><a href="#cb28-468" aria-hidden="true" tabindex="-1"></a> }</span> 1106<span id="cb28-469"><a href="#cb28-469" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> (progress <span class="op">></span> <span class="dv">10</span> <span class="op">&&</span> <span class="op">!</span>progress10) {</span> 1107<span id="cb28-470"><a href="#cb28-470" aria-hidden="true" tabindex="-1"></a> mutable progress10 <span class="op">=</span> <span class="kw">true</span><span class="op">;</span></span> 1108<span id="cb28-471"><a href="#cb28-471" aria-hidden="true" tabindex="-1"></a>
1108 <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="st">'hit 10'</span>)</span> 1109<span id="cb28-472"><a href="#cb28-472" aria-hidden="true" tabindex="-1"></a> <span class="bu">window</span><span class="op">.</span><span class="fu">plausible</span>(<span class="st">'pictures-pensions progress'</span><span class="op">,</span> { <span class="dt">props</span><span class="op">:</span> {<span class="dt">index</span><span class="op">:</span> <span class="dv">10</span>}})</span> 1110<span id="cb28-473"><a href="#cb28-473" aria-hidden="true" tabindex="-1"></a></span> 1111<span id="cb28-474"><a href="#cb28-474" aria-hidden="true" tabindex="-1"></a> }</span> 1112<span id="cb28-475"><a href="#cb28-475" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> (progress <span class="op">></span> <span class="dv">15</span> <span class="op">&&</span> <span class="op">!</span>progress15) {</span> 1113<span id="cb28-476"><a href="#cb28-476" aria-hidden="true" tabindex="-1"></a> mutable progress15 <span class="op">=</span> <span class="kw">true</span><span class="op">;</span></span> 1114<span id="cb28-477"><a href="#cb28-477" aria-hidden="true" tabindex="-1"></a>
1114 <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="st">'hit 15'</span>)</span> 1115<span id="cb28-478"><a href="#cb28-478" aria-hidden="true" tabindex="-1"></a> <span class="bu">window</span><span class="op">.</span><span class="fu">plausible</span>(<span class="st">'pictures-pensions progress'</span><span class="op">,</span> { <span class="dt">props</span><span class="op">:</span> {<span class="dt">index</span><span class="op">:</span> <span class="dv">15</span>}})</span> 1116<span id="cb28-479"><a href="#cb28-479" aria-hidden="true" tabindex="-1"></a></span> 1117<span id="cb28-480"><a href="#cb28-480" aria-hidden="true" tabindex="-1"></a> }</span> 1118<span id="cb28-481"><a href="#cb28-481" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> (progress <span class="op">></span> <span class="dv">20</span> <span class="op">&&</span> <span class="op">!</span>progress20) {</span> 1119<span id="cb28-482"><a href="#cb28-482" aria-hidden="true" tabindex="-1"></a> mutable progress20 <span class="op">=</span> <span class="kw">true</span><span class="op">;</span></span> 1120<span id="cb28-483"><a href="#cb28-483" aria-hidden="true" tabindex="-1"></a>
1120 <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="st">'hit 20'</span>)</span> 1121<span id="cb28-484"><a href="#cb28-484" aria-hidden="true" tabindex="-1"></a> <span class="bu">window</span><span class="op">.</span><span class="fu">plausible</span>(<span class="st">'pictures-pensions progress'</span><span class="op">,</span> { <span class="dt">props</span><span class="op">:</span> {<span class="dt">index</span><span class="op">:</span> <span class="dv">20</span>}})</span> 1122<span id="cb28-485"><a href="#cb28-485" aria-hidden="true" tabindex="-1"></a></span> 1123<span id="cb28-486"><a href="#cb28-486" aria-hidden="true" tabindex="-1"></a> }</span> 1124<span id="cb28-487"><a href="#cb28-487" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> (progress <span class="op">></span> <span class="dv">25</span> <span class="op">&&</span> <span class="op">!</span>progress25) {</span> 1125<span id="cb28-488"><a href="#cb28-488" aria-hidden="true" tabindex="-1"></a> mutable progress25 <span class="op">=</span> <span class="kw">true</span><span class="op">;</span></span> 1126<span id="cb28-489"><a href="#cb28-489" aria-hidden="true" tabindex="-1"></a>
1126 <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="st">'hit 25'</span>)</span> 1127<span id="cb28-490"><a href="#cb28-490" aria-hidden="true" tabindex="-1"></a> <span class="bu">window</span><span class="op">.</span><span class="fu">plausible</span>(<span class="st">'pictures-pensions progress'</span><span class="op">,</span> { <span class="dt">props</span><span class="op">:</span> {<span class="dt">index</span><span class="op">:</span> <span class="dv">25</span>}})</span> 1128<span id="cb28-491"><a href="#cb28-491" aria-hidden="true" tabindex="-1"></a></span> 1129<span id="cb28-492"><a href="#cb28-492" aria-hidden="true" tabindex="-1"></a> }</span> 1130<span id="cb28-493"><a href="#cb28-493" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> (progress <span class="op">></span> <span class="dv">30</span> <span class="op">&&</span> <span class="op">!</span>progress30) {</span> 1131<span id="cb28-494"><a href="#cb28-494" aria-hidden="true" tabindex="-1"></a> mutable progress30 <span class="op">=</span> <span class="kw">true</span><span class="op">;</span></span> 1132<span id="cb28-495"><a href="#cb28-495" aria-hidden="true" tabindex="-1"></a>
1132 <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="st">'hit 30'</span>) <span class="co">// not used</span></span> 1133<span id="cb28-496"><a href="#cb28-496" aria-hidden="true" tabindex="-1"></a> <span class="bu">window</span><span class="op">.</span><span class="fu">plausible</span>(<span class="st">'pictures-pensions progress'</span><span class="op">,</span> { <span class="dt">props</span><span class="op">:</span> {<span class="dt">index</span><span class="op">:</span> <span class="dv">30</span>}})</span> 1134<span id="cb28-497"><a href="#cb28-497" aria-hidden="true" tabindex="-1"></a></span> 1135<span id="cb28-498"><a href="#cb28-498" aria-hidden="true" tabindex="-1"></a> }</span> 1136<span id="cb28-499"><a href="#cb28-499" aria-hidden="true" tabindex="-1"></a> }</span> 1137<span id="cb28-500"><a href="#cb28-500" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div> 1138<div class="cell-output cell-output-display"> 1139<div> 1140<div id="ojs-cell-14-1" data-nodetype="declaration"> 1141 1142</div> 1143</div> 1144</div> 1145<div class="cell-output cell-output-display"> 1146<div> 1147<div id="ojs-cell-14-2" data-nodetype="declaration"> 1148 1149</div> 1150</div> 1151</div> 1152<div class="cell-output cell-output-display"> 1153<div> 1154<div id="ojs-cell-14-3" data-nodetype="declaration"> 1155 1156</div> 1157</div> 1158</div> 1159<div class="cell-output cell-output-display"> 1160<div> 1161<div id="ojs-cell-14-4" data-nodetype="declaration"> 1162 1163</div> 1164</div> 1165</div> 1166<div class="cell-output cell-output-display"> 1167<div> 1168<div id="ojs-cell-14-5" data-nodetype="declaration"> 1169 1170</div> 1171</div> 1172</div> 1173<div class="cell-output cell-output-display"> 1174<div> 1175<div id="ojs-cell-14-6" data-nodetype="declaration"> 1176 1177</div> 1178</div> 1179</div> 1180<div class="cell-output cell-output-display"> 1181<div> 1182<div id="ojs-cell-14-7" data-nodetype="expression"> 1183 1184</div> 1185</div> 1186</div> 1187</div> 1188</details> 1189 1190 1191<div class="ojs-auto-generated hidden">
1192<script type="ojs-module-contents"> 1193eyJjb250ZW50cyI6WyAgeyJtZXRob2ROYW1lIjoiaW50ZXJwcmV0IiwiaW5saW5lIjoidHJ1ZSIsInNvdXJjZSI6Imh0bC5odG1sYDxzcGFuPiR7ZDMuZm9ybWF0KFwiLC4wZlwiKShzYWxhcnlfMF9pbil9PC9zcGFuPmAiLCAiY2VsbE5hbWUiOiJvanMtZWxlbWVudC1pZC0xIn1dfQ== 1194</script>
1194 1195</div> 1196 1197 1198<div id="quarto-appendix" class="default"><section id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes"><h2 class="anchored quarto-appendix-heading">Footnotes</h2> 1199 1200<ol> 1201<li id="fn1"><p>often there are taxes on pension income - so that it might be better to say that tax is <em>deferred</em> rather than relieved whenever we save<a href="#fnref1" class="footnote-back" role="doc-backlink">â©ï¸</a></p></li> 1202</ol> 1203</section></div></main> <!-- /main -->
1204<script type="ojs-module-contents"> 1205eyJjb250ZW50cyI6W3sibWV0aG9kTmFtZSI6ImludGVycHJldCIsImNlbGxOYW1lIjoib2pzLWNlbGwtMSIsImlubGluZSI6ZmFsc2UsInNvdXJjZSI6Im1kYEFzc3VtaW5nICoqJHtkMy5mb3JtYXQoJy4xJScpKHVuaXRfZ3Jvd3RoX3JhdGVfaW4pfSBjb21wb3VuZCByZXR1cm5zKiogZWFjaCB5ZWFyYFxuIn0seyJtZXRob2ROYW1lIjoiaW50ZXJwcmV0IiwiY2VsbE5hbWUiOiJvanMtY2VsbC0yIiwiaW5saW5lIjpmYWxzZSwic291cmNlIjoiLy8gc29tZSByZWFjdGl2ZSBpc3N1ZSBjYXVzaW5nIHRyaWdnZXIgdG8gZmFpbD8gbW92ZWQgQGNyLXBlbnMgdG8gOjo6e2ZvY3VzLW9uPVwiY3ItcGVuc1wifSBidXQgZGlkbid0IGhlbHAgIVxubWRgVGhlIHRheCByZWxpZWYgaXMgPHNwYW4gY2xhc3M9XCJtXCI+KirigqwgJHsvKm1vZGVsLmpzLmVtcGVlX2NvbnRyaWJ1dGlvbl90YXhfcmVsaWVmKHsuLi5jdXJzb3JfXzEsIGFnZV9pbjogNjB9KSovNDAwfSoqPC9zcGFuPiBzbyB0aGF0IHRoZSA8c3BhbiBjbGFzcz1cImNlbGwtaGwgY29zdFwiPmVmZmVjdGl2ZSBjb3N0PC9zcGFuPiBvZiBzYXZpbmcgPHNwYW4gY2xhc3M9XCJtXCI+KirigqwgMSwwMDAqKjwvc3Bhbj4gaXMganVzdCA8c3BhbiBjbGFzcz1cIm1cIj4qKuKCrCAkey8qbW9kZWwuanMuZW1wZWVfY29udHJpYnV0aW9uX2Nvc3Qoey4uLmN1cnNvcl9fMSwgYWdlX2luOiA2MH0pKi82MDB9Kio8L3NwYW4+YFxuIn0seyJtZXRob2ROYW1lIjoiaW50ZXJwcmV0IiwiY2VsbE5hbWUiOiJvanMtY2VsbC0zIiwiaW5saW5lIjpmYWxzZSwic291cmNlIjoiLy9tZGAqKiR7ZDMuZm9ybWF0KCcuMSUnKSh1bml0X2dyb3d0aF9yYXRlX2luKX0qKmBcbi8vbWRgKioke2QzLmZvcm1hdCgnLC4wZicpKHNhbGFyeV8wX2luKX0qKiBzYWxhcnlgXG5cbi8vIGNoZWNrX2Nmc192c19mdW5kX3ZhbHVlIGlzIHdlYWtlbmVkIGFzIGEgY2hlY2tcbnZpeiA9IGVtYmVkKCcjdml6JyxzcGVjLCB7cmVuZGVyZXI6ICdzdmcnLCBhY3Rpb25zOmZhbHNlLCB0b29sdGlwOmZhbHNlfSk7XG4ifSx7Im1ldGhvZE5hbWUiOiJpbnRlcnByZXQiLCJjZWxsTmFtZSI6Im9qcy1jZWxsLTQiLCJpbmxpbmUiOmZhbHNlLCJzb3VyY2UiOiJcbi8vIFNDUk9MTCBJTlRFUkFDVElPTiBMT0dJQ1xucHJvZ3Jlc3MgPSBjclRyaWdnZXJJbmRleCtjclRyaWdnZXJQcm9ncmVzcy0oY3JUcmlnZ2VyUHJvZ3Jlc3M+MC45OTk5OTk/MTowKSsoY3JUcmlnZ2VyUHJvZ3Jlc3M8MC4wMDAwMDE/MTowKVxuXG5vMCA9IDFcblxuYWdlXzFfaW5fc2NhbGUgPSBkMy5zY2FsZUxpbmVhcigpLmRvbWFpbihbbzArLjUsIG8wKzEuNV0pLnJhbmdlKFs1MSwgNzBdKS5jbGFtcCh0cnVlKVxuYWdlXzFfaW4gPSBNYXRoLnJvdW5kKGFnZV8xX2luX3NjYWxlKHByb2dyZXNzKSlcblxubzEgPSA0XG51bml0X2dyb3d0aF9yYXRlX2luX3NjYWxlID0gZDMuc2NhbGVMaW5lYXIoKS5kb21haW4oW28xKy40LCBvMSsxLjVdKS5yYW5nZShbMCwgMC4wNl0pLmNsYW1wKHRydWUpXG51bml0X2dyb3d0aF9yYXRlX2luID0gdW5pdF9ncm93dGhfcmF0ZV9pbl9zY2FsZShwcm9ncmVzcylcblxubzIgPSA3XG5zYWxhcnlfMF9pbl9zY2FsZSA9IGQzLnNjYWxlTGluZWFyKCkuZG9tYWluKFtvMisuOCwgbzIrMS41XSkucmFuZ2UoWzEwMDAwLCA1MDAwMF0pLmNsYW1wKHRydWUpXG5zYWxhcnlfMF9pbiA9IHNhbGFyeV8wX2luX3NjYWxlKHByb2dyZXNzKVxuXG5zdGF0ZXkgPSAocHJvZ3Jlc3MgPiAxMC40ICYmIHByb2dyZXNzIDwgMTMuNSkgfHwgcHJvZ3Jlc3MgPiAyMS41ICYmIHByb2dyZXNzIDwgMjUuM1xuXG5vZmxhc2ggPSA5XG5cbmZsYXNoID0gZDMuc2NhbGVMaW5lYXIoKS5kb21haW4oWzAuMiwwXSkucmFuZ2UoWzAsMV0pLmNsYW1wKHRydWUpKE1hdGguYWJzKHByb2dyZXNzLTkuNykpICsgZDMuc2NhbGVMaW5lYXIoKS5kb21haW4oWzAuMiwwXSkucmFuZ2UoWzAsMV0pLmNsYW1wKHRydWUpKE1hdGguYWJzKHByb2dyZXNzLTE0LjcpKSBcblxuXG5mbGFzaGFsbCA9IGQzLnNjYWxlTGluZWFyKCkuZG9tYWluKFswLjIsMF0pLnJhbmdlKFswLDFdKS5jbGFtcCh0cnVlKShNYXRoLmFicyhwcm9ncmVzcy0xNS43KSkgKyBkMy5zY2FsZUxpbmVhcigpLmRvbWFpbihbMC45LDBdKS5yYW5nZShbMCwyXSkuY2xhbXAodHJ1ZSkoTWF0aC5hYnMocHJvZ3Jlc3MtMjAuMykpICsgZDMuc2NhbGVMaW5lYXIoKS5kb21haW4oWzAuNiwwXSkucmFuZ2UoWzAsMV0pLmNsYW1wKHRydWUpKE1hdGguYWJzKHByb2dyZXNzLTI2LjgpKSArIChwcm9ncmVzcyA+IDI2LjggPyAxMCA6IDApXG5cbm91dGZsb3dzX29wYWNpdHkgPSBkMy5zY2FsZUxpbmVhcigpLmRvbWFpbihbMTYuNSwxN10pLnJhbmdlKFswLDFdKS5jbGFtcCh0cnVlKShwcm9ncmVzcylcblxue1xuaWYgKHByb2dyZXNzID4gMTIpIHtcbiAgdml6LnZpZXcuc2lnbmFsKCd5ZG9tYWluX3gnLCAocHJvZ3Jlc3MgPCAyMCA/IHByb2dyZXNzLTEyIDogcHJvZ3Jlc3MgLSAyMy45KSkucmVzaXplKCkucnVuKCk7XG4vL3Zpei52aWV3LnNpZ25hbCgneWRvbWFpbl9vdmVycmlkZScsIFswLDUwMDBdKS5yZXNpemUoKS5ydW4oKTtcbi8vY29uc29sZS5sb2codml6LnZpZXcuc2lnbmFsKCd5ZG9tYWluJykpXG59XG59XG5cbnZpei52aWV3LnNpZ25hbCgnb3V0Zmxvd3Nfb3BhY2l0eScsIG91dGZsb3dzX29wYWNpdHkpLy8ucnVuKCk7XG52aXoudmlldy5zaWduYWwoJ2ZsYXNoJywgZmxhc2gpLy8ucnVuKCk7XG52aXoudmlldy5zaWduYWwoJ2ZsYXNoYWxsJywgZmxhc2hhbGwpLnJ1bigpO1xuXG5cblxubzMgPSAxMFxuZW1wZXJfbWF0Y2hpbmdfcmF0ZV9pbl9zY2FsZSA9IGQzLnNjYWxlTGluZWFyKCkuZG9tYWluKFtvMysuNSwgbzMrMS41XSkucmFuZ2UoWzAsIDFdKS5jbGFtcCh0cnVlKVxuZW1wZXJfbWF0Y2hpbmdfcmF0ZV9pbiA9IGVtcGVyX21hdGNoaW5nX3JhdGVfaW5fc2NhbGUocHJvZ3Jlc3MpXG5cblxubzQgPSAxN1xuY29udHJpYnV0aW9uX2NoYXJnZV9yYXRlX2luID0gZDMuc2NhbGVMaW5lYXIoKS5kb21haW4oW280Ky41LCBvNCsxLjVdKS5yYW5nZShbMCwgMC4wNV0pLmNsYW1wKHRydWUpKHByb2dyZXNzKVxubWFuYWdlbWVudF9jaGFyZ2VfcmF0ZV9pbiA9IGQzLnNjYWxlTGluZWFyKCkuZG9tYWluKFtvNCsxLjUsIG80KzJdKS5yYW5nZShbMCwgMC4wMV0pLmNsYW1wKHRydWUpKHByb2dyZXNzKVxubzUgPSAyMVxuYWdlXzBfaW4gPSBNYXRoLnJvdW5kKGQzLnNjYWxlTGluZWFyKCkuZG9tYWluKFtvNSswLjcsIG81KzEuNV0pLnJhbmdlKFs1MCw0MF0pLmNsYW1wKHRydWUpKHByb2dyZXNzKSlcblxuXG4vL2NvbnRyaWJ1dGlvbl9jaGFyZ2VfcmF0ZV9pbiwgbWFuYWdlbWVudF9jaGFyZ2VfcmF0ZV9pblxuXG5cblxuIn0seyJtZXRob2ROYW1lIjoiaW50ZXJwcmV0IiwiY2VsbE5hbWUiOiJvanMtY2VsbC01IiwiaW5saW5lIjpmYWxzZSwic291cmNlIjoiLy8gYm9ycm93ZWQgZnJvbSBjbG9zZXJlYWQuZGV2XG5tZGBBY3RpdmUgc3RpY2t5OiAke2NyQWN0aXZlU3RpY2t5fWBcbm1kYEFjdGl2ZSB0cmlnZ2VyOiAke2NyVHJpZ2dlckluZGV4fWBcbm1kYFRyaWdnZXIgcHJvZ3Jlc3M6ICR7KGNyVHJpZ2dlclByb2dyZXNzICogMTAwKS50b0ZpeGVkKDEpfSVgXG5tZGBTY3JvbGwgZGlyZWN0aW9uOiAke2NyRGlyZWN0aW9ufWBcbm1kYFByb2dyZXNzIEJsb2NrIHByb2dyZXNzOiAkeyhjclByb2dyZXNzQmxvY2sgKiAxMDApLnRvRml4ZWQoMSl9JWBcbm1kYC0tLS0tYFxubWRgc2FsYXJ5XzAgJHtzYWxhcnlfMF9pbn1gXG4ifSx7Im1ldGhvZE5hbWUiOiJpbnRlcnByZXQiLCJjZWxsTmFtZSI6Im9qcy1jZWxsLTYiLCJpbmxpbmUiOmZhbHNlLCJzb3VyY2UiOiJpbXBvcnQge3NwZWMgYXMgc3BlY199IGZyb20gJy4vc3BlYy5qcydcblxuc3BlYyA9IHNwZWNfKHdpZHRoLCB5KVxuIn0seyJtZXRob2ROYW1lIjoiaW50ZXJwcmV0IiwiY2VsbE5hbWUiOiJvanMtY2VsbC03IiwiaW5saW5lIjpmYWxzZSwic291cmNlIjoidml6LnZpZXcuZGF0YSgnZGF0YScsIFsuLi5kYXRhXSkucmVzaXplKCkucnVuKCk7XG5cbiJ9LHsibWV0aG9kTmFtZSI6ImludGVycHJldCIsImNlbGxOYW1lIjoib2pzLWNlbGwtOCIsImlubGluZSI6ZmFsc2UsInNvdXJjZSI6IndpbmRvdy5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudCgncmVzaXplJykpOyAvLyB3aXRob3V0IHRoaXMsIG15IG93biBmb2N1cy1vbiBibG9ja3MgZG9uJ3QgZ2V0IHRyaWdnZXJlZCAoZm9yIHNvbWUgcmVhc29uIG9ubHkgbXkgb25lcyAtIE9KUyBWYXJpYWJsZXMgb25lcyB3b3JrKVxuLy8gVGhleSB3b3JrIHdoZW4gSSByZXNpemUuIFNvIHRyaWdnZXJpbmcgdGhpcyBwcm9ncmFtbWF0aWNhbGx5LlxuIn0seyJtZXRob2ROYW1lIjoiaW50ZXJwcmV0IiwiY2VsbE5hbWUiOiJvanMtY2VsbC05IiwiaW5saW5lIjpmYWxzZSwic291cmNlIjoiZW1iZWRfID0gcmVxdWlyZShcInZlZ2EtZW1iZWRcIilcblxuZW1iZWQgPSAoYSxiLG9wdGlvbnMpID0+IGVtYmVkXyhhLGIsIHtyZW5kZXJlcjonc3ZnJywgLyp0aGVtZTonY2FyYm9uZzEwJywqLyBhY3Rpb25zLCAuLi5vcHRpb25zfSk7XG4ifSx7Im1ldGhvZE5hbWUiOiJpbnRlcnByZXQiLCJjZWxsTmFtZSI6Im9qcy1jZWxsLT
1205EwIiwiaW5saW5lIjpmYWxzZSwic291cmNlIjoidmlld29mIGFjdGlvbnMgPSBJbnB1dHMudG9nZ2xlKHtsYWJlbDondmVnYS1lbWJlZCBhY3Rpb25zPycsIHZhbHVlOiBmYWxzZX0pXG4ifSx7Im1ldGhvZE5hbWUiOiJpbnRlcnByZXQiLCJjZWxsTmFtZSI6Im9qcy1jZWxsLTExIiwiaW5saW5lIjpmYWxzZSwic291cmNlIjoiaGVscGVycyA9IGltcG9ydChcbiAgXCJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvZ2gvZGVjbGFubi9jYWxjdWxhbmctanMtYnJvd3Nlci1kZXZAbWFpbi9oZWxwZXJzLmpzXCJcbilcblxuY2FsY3VsYW5nID0gaW1wb3J0KFxuICBcImh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9naC9jYWxjdWxhbmcvY2FsY3VsYW5nQGFsbF9jdWwvcGFja2FnZXMvc3RhbmRhbG9uZS9pbmRleC5qc1wiXG4pXG5cbnByZV9mZXRjaCA9IChhd2FpdCBpbXBvcnQoXG4gIFwiaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L2doL2NhbGN1bGFuZy9jYWxjdWxhbmdAYWxsX2N1bC9wYWNrYWdlcy9zdGFuZGFsb25lL3ByZV9mZXRjaC5tanNcIlxuKSkucHJlX2ZldGNoXG5cblxuZnMwID0gYXdhaXQgcHJlX2ZldGNoKHtcbiAgXCJlbnRyeXBvaW50LmN1bC5qc1wiOiBhd2FpdCBGaWxlQXR0YWNobWVudCgnLi9jdWwvcGVuc2lvbi1jYWxjdWxhdG9yLW92ZXJyaWRlcy5jdWwuanMnKS50ZXh0KClcbn0pXG5cbm1vZGVsID0gYXdhaXQgY2FsY3VsYW5nLmNvbXBpbGUoe2VudHJ5cG9pbnQ6ICdlbnRyeXBvaW50LmN1bC5qcycsIGZzOiBmczB9KVxud2luZG93Lm1vZGVsID0gbW9kZWxcblxuXG5cbmZvcm11bGFlID0gWydlbXBlZV9jb250cmlidXRpb25fdGF4X3JlbGllZicsICdlbXBlZV9jb250cmlidXRpb25fY29zdCcsICdlbXBlcl9jb250cmlidXRpb24nLCAnZnVuZF9ncm93dGgnLCAnY29udHJpYnV0aW9uX2NoYXJnZScsICdtYW5hZ2VtZW50X2NoYXJnZSddXG5cblxuY3Vyc29yXzAgPSAoe2FnZV8wX2luLCBmdW5kX3ZhbHVlXzBfaW46MCwgdW5pdF9ncm93dGhfcmF0ZV9pbjowLCByZXRpcmVtZW50X2FnZV9pbjo2NSwgbWlzc2VkX2NvbnRyaWJ1dGlvbl9hZ2VfaW46MTUsIHNhbGFyeV9hZ2VfMF9pbjo1MCwgc2FsYXJ5XzBfaW4sIHNhbGFyeV9pbmZsYXRpb25fcmF0ZV9pbjowLCAvKmVtcGVlX2NvbnRyaWJ1dGlvbl9yYXRlX2luOi4xIE1vdmVkIHRvIGZpeGVkIGNvbnRyaWJ1dGlvbiBhbW91bnQgKi9lbXBlcl9tYXRjaGluZ19yYXRlX2luLCBjb250cmlidXRpb25fY2hhcmdlX3JhdGVfaW4sIG1hbmFnZW1lbnRfY2hhcmdlX3JhdGVfaW4sIGFnZV8xX2lufSlcblxuY3Vyc29yID0gY3Vyc29yXzBcblxuY3Vyc29yXzEgPSAoey4uLmN1cnNvciwgdW5pdF9ncm93dGhfcmF0ZV9pbn0pXG5cbndpbmRvdy5jdXJzb3JfMCA9IGN1cnNvcl8wXG53aW5kb3cuY3Vyc29yID0gY3Vyc29yXzFcbi8vY3Vyc29yXzIgPSAoey4uLmN1cnNvcl8xLCBlbXBlcl9tYXRjaGluZ19yYXRlX2lufSlcblxudml6LnZpZXcuc2lnbmFsKCdzdGF0ZXknLCBzdGF0ZXkpLnJ1bigpXG4vL3Zpei52aWV3LnNpZ25hbCgnaW5wdXRfY3Vyc29yX2lkX3NpZ25hbCcsIHN0YXRleSA/IDEgOiAwKS5ydW4oKVxuXG5jdXJzb3JfXzAgPSB7XG4gIGlmIChwcm9ncmVzcyA8IDE3KSByZXR1cm4gKHsuLi5jdXJzb3JfMSxlbXBlcl9tYXRjaGluZ19yYXRlX2luOjB9KVxuICBlbHNlIGlmIChwcm9ncmVzcyA8IDIxKSByZXR1cm4gKHsuLi5jdXJzb3JfMSwgbWFuYWdlbWVudF9jaGFyZ2VfcmF0ZV9pbjowLCBjb250cmlidXRpb25fY2hhcmdlX3JhdGVfaW46MH0pXG4gIGVsc2UgcmV0dXJuICh7Li4uY3Vyc29yXzEsIGFnZV8wX2luOjUwfSlcbn1cblxuY3Vyc29yX18xID0ge1xuICByZXR1cm4gY3Vyc29yXzFcbn1cblxuZGF0YSA9IGhlbHBlcnMuY2FsY3VkYXRhKHtcbiAgbW9kZWxzOiBbbW9kZWwuanNdLFxuICBpbnB1dF9kb21haW5zOiB7YWdlX2luOiBfLnJhbmdlKGN1cnNvci5hZ2VfMF9pbixjdXJzb3IucmV0aXJlbWVudF9hZ2VfaW4pfSxcbiAgaW5wdXRfY3Vyc29yczogW2N1cnNvcl9fMCwgY3Vyc29yX18xXSxcbiAgb3V0cHV0czogWy4uLmZvcm11bGFlLCAnY2hlY2tfY2ZzX3ZzX2Z1bmRfdmFsdWUnXSxcbiAgcGl2b3Q6IGZhbHNlXG59KVxuXG52aWV3b2Ygc2hhcmVkX3lfc2NhbGUgPSBJbnB1dHMudG9nZ2xlKHtsYWJlbDogJ3NoYXJlZCB5IHNjYWxlPycsIHZhbHVlOiB0cnVlfSlcblxuXG55ID0gc2hhcmVkX3lfc2NhbGUgPyAneV9zaGFyZWQnIDogJ3knXG5cbmYgPSBkMy5mb3JtYXQoJywuMmYnKVxuXG4ifSx7Im1ldGhvZE5hbWUiOiJpbnRlcnByZXQiLCJjZWxsTmFtZSI6Im9qcy1jZWxsLT
1205EyIiwiaW5saW5lIjpmYWxzZSwic291cmNlIjoiXG4vLyBJIG5lZWQgb2pzIGJsb2NrcyB0byBiZSBpbnNpZGUgZm9jdXMtb24gYmxvY2tzLCBvciB0aGV5IGJyZWFrIGEgdHJpZ2dlclxuZSA9IGQzLnN1bShkYXRhLmZpbHRlcihkID0+IGQuaW5wdXRfY3Vyc29yX2lkID09IDEgJiYgZC5mb3JtdWxhID09XCJlbXBlZV9jb250cmlidXRpb25fY29zdFwiKSwgZCA9PiBkLnZhbHVlKVxuIn0seyJtZXRob2ROYW1lIjoiaW50ZXJwcmV0IiwiY2VsbE5hbWUiOiJvanMtY2VsbC0xMyIsImlubGluZSI6ZmFsc2UsInNvdXJjZSI6IntcbmZvciAoY29uc3QgZWwgb2YgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnY3ItY29sdW1uLXNjcmVlbicpKSB7XG4gIGVsLmNsYXNzTGlzdC5yZW1vdmUoJ2NyLWNvbHVtbi1zY3JlZW4nKVxufVxufVxuIn0seyJtZXRob2ROYW1lIjoiaW50ZXJwcmV0IiwiY2VsbE5hbWUiOiJvanMtY2VsbC0xNCIsImlubGluZSI6ZmFsc2UsInNvdXJjZSI6Ii8vIFBsYXVzaWJsZSBvcHRpb25hbCBhbmFseXRpY3NcblxuICBtdXRhYmxlIHByb2dyZXNzNSA9IGZhbHNlO1xuICBtdXRhYmxlIHByb2dyZXNzMTAgPSBmYWxzZTtcbiAgbXV0YWJsZSBwcm9ncmVzczE1ID0gZmFsc2U7XG4gIG11dGFibGUgcHJvZ3Jlc3MyMCA9IGZhbHNlO1xuICBtdXRhYmxlIHByb2dyZXNzMjUgPSBmYWxzZTtcbiAgbXV0YWJsZSBwcm9ncmVzczMwID0gZmFsc2U7XG5cbntcbiAgaWYgKHdpbmRvdy5wbGF1c2libGUpIHtcbiAgICBpZiAocHJvZ3Jlc3MgPiA1ICYmICFwcm9ncmVzczUpIHtcbiAgICAgIG11dGFibGUgcHJvZ3Jlc3M1ID0gdHJ1ZTtcbiAgICAgIGNvbnNvbGUubG9nKCdoaXQgNScpXG4gICAgICB3aW5kb3cucGxhdXNpYmxlKCdwaWN0dXJlcy1wZW5zaW9ucyBwcm9ncmVzcycsIHsgcHJvcHM6IHtpbmRleDogNX19KVxuICAgIH1cbiAgICBpZiAocHJvZ3Jlc3MgPiAxMCAmJiAhcHJvZ3Jlc3MxMCkge1xuICAgICAgbXV0YWJsZSBwcm9ncmVzczEwID0gdHJ1ZTtcbiAgICAgIGNvbnNvbGUubG9nKCdoaXQgMTAnKVxuICAgICAgd2luZG93LnBsYXVzaWJsZSgncGljdHVyZXMtcGVuc2lvbnMgcHJvZ3Jlc3MnLCB7IHByb3BzOiB7aW5kZXg6IDEwfX0pXG5cbiAgICB9XG4gICAgaWYgKHByb2dyZXNzID4gMTUgJiYgIXByb2dyZXNzMTUpIHtcbiAgICAgIG11dGFibGUgcHJvZ3Jlc3MxNSA9IHRydWU7XG4gICAgICBjb25zb2xlLmxvZygnaGl0IDE1JylcbiAgICAgIHdpbmRvdy5wbGF1c2libGUoJ3BpY3R1cmVzLXBlbnNpb25zIHByb2dyZXNzJywgeyBwcm9wczoge2luZGV4OiAxNX19KVxuXG4gICAgfVxuICAgIGlmIChwcm9ncmVzcyA+IDIwICYmICFwcm9ncmVzczIwKSB7XG4gICAgICBtdXRhYmxlIHByb2dyZXNzMjAgPSB0cnVlO1xuICAgICAgY29uc29sZS5sb2coJ2hpdCAyMCcpXG4gICAgICB3aW5kb3cucGxhdXNpYmxlKCdwaWN0dXJlcy1wZW5zaW9ucyBwcm9ncmVzcycsIHsgcHJvcHM6IHtpbmRleDogMjB9fSlcblxuICAgIH1cbiAgICBpZiAocHJvZ3Jlc3MgPiAyNSAmJiAhcHJvZ3Jlc3MyNSkge1xuICAgICAgbXV0YWJsZSBwcm9ncmVzczI1ID0gdHJ1ZTtcbiAgICAgIGNvbnNvbGUubG9nKCdoaXQgMjUnKVxuICAgICAgd2luZG93LnBsYXVzaWJsZSgncGljdHVyZXMtcGVuc2lvbnMgcHJvZ3Jlc3MnLCB7IHByb3BzOiB7aW5kZXg6IDI1fX0pXG5cbiAgICB9XG4gICAgaWYgKHByb2dyZXNzID4gMzAgJiYgIXByb2dyZXNzMzApIHtcbiAgICAgIG11dGFibGUgcHJvZ3Jlc3MzMCA9IHRydWU7XG4gICAgICBjb25zb2xlLmxvZygnaGl0IDMwJykgLy8gbm90IHVzZWRcbiAgICAgIHdpbmRvdy5wbGF1c2libGUoJ3BpY3R1cmVzLXBlbnNpb25zIHByb2dyZXNzJywgeyBwcm9wczoge2luZGV4OiAzMH19KVxuXG4gICAgfVxuICB9XG59XG4ifSx7Im1ldGhvZE5hbWUiOiJpbnRlcnByZXRRdWlldCIsInNvdXJjZSI6InNoaW55SW5wdXQoJ2FjdGlvbnMnKSJ9LHsibWV0aG9kTmFtZSI6ImludGVycHJldFF1aWV0Iiwic291cmNlIjoic2hpbnlJbnB1dCgnc2hhcmVkX3lfc2NhbGUnKSJ9XX0= 1206</script>
vendor: 1 bytes, line 1206
1206
1207<script type="module"> 1208if (window.location.protocol === "file:") { alert("The OJS runtime does not work with file:// URLs. Please use a web server to view this document."); } 1209window._ojs.paths.runtimeToDoc = "../../posts/pictures-pensions"; 1210window._ojs.paths.runtimeToRoot = "../.."; 1211window._ojs.paths.docToRoot = "../.."; 1212window._ojs.selfContained = false; 1213window._ojs.runtime.interpretFromScriptTags(); 1214</script>
vendor: 1 bytes, line 1214
1214
1215<script id="quarto-html-after-body" type="application/javascript"> 1216 window.document.addEventListener("DOMContentLoaded", function (event) { 1217 const icon = "î§"; 1218 const anchorJS = new window.AnchorJS(); 1219 anchorJS.options = { 1220 placement: 'right', 1221 icon: icon 1222 }; 1223 anchorJS.add('.anchored'); 1224 const isCodeAnnotation = (el) => { 1225 for (const clz of el.classList) { 1226 if (clz.startsWith('code-annotation-')) { 1227 return true; 1228 } 1229 } 1230 return false; 1231 } 1232 const onCopySuccess = function(e) { 1233 // button target 1234 const button = e.trigger; 1235 // don't keep focus 1236 button.blur(); 1237 // flash "checked" 1238 button.classList.add('code-copy-button-checked'); 1239 var currentTitle = button.getAttribute("title"); 1240 button.setAttribute("title", "Copied!"); 1241 let tooltip; 1242 if (window.bootstrap) { 1243 button.setAttribute("data-bs-toggle", "tooltip"); 1244 button.setAttribute("data-bs-placement", "left"); 1245 button.setAttribute("data-bs-title", "Copied!"); 1246 tooltip = new bootstrap.Tooltip(button, 1247 { trigger: "manual", 1248 customClass: "code-copy-button-tooltip", 1249 offset: [0, -8]}); 1250 tooltip.show(); 1251 } 1252 setTimeout(function() { 1253 if (tooltip) { 1254 tooltip.hide(); 1255 button.removeAttribute("data-bs-title"); 1256 button.removeAttribute("data-bs-toggle"); 1257 button.removeAttribute("data-bs-placement"); 1258 } 1259 button.setAttribute("title", currentTitle); 1260 button.classList.remove('code-copy-button-checked'); 1261 }, 1000); 1262 // clear code selection 1263 e.clearSelection(); 1264 } 1265 const getTextToCopy = function(trigger) { 1266 const outerScaffold = trigger.parentElement.cloneNode(true); 1267 const codeEl = outerScaffold.querySelector('code'); 1268 for (const childEl of codeEl.children) { 1269 if (isCodeAnnotation(childEl)) { 1270 childEl.remove(); 1271 } 1272 } 1273 return codeEl.innerText; 1274 } 1275 const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', { 1276 text: getTextToCopy 1277 }); 1278 clipboard.on('success', onCopySuccess); 1279 if (window.document.getElementById('quarto-embedded-source-code-modal')) { 1280 const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', { 1281 text: getTextToCopy, 1282 container: window.document.getElementById('quarto-embedded-source-code-modal') 1283 }); 1284 clipboardModal.on('success', onCopySuccess); 1285 } 1286 var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//); 1287 var mailtoRegex = new RegExp(/^mailto:/); 1288 var filterRegex = new RegExp("https:\/\/calcwithdec\.dev"); 1289 var isInternal = (href) => { 1290 return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href); 1291 } 1292 // Inspect non-navigation links and adorn them if external 1293 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)'); 1294 for (var i=0; i<links.length; i++) { 1295 const link = links[i]; 1296 if (!isInternal(link.href)) { 1297 // undo the damage that might have been done by quarto-nav.js in the case of 1298 // links that we want to consider external 1299 if (link.dataset.originalHref !== undefined) { 1300 link.href = link.dataset.originalHref; 1301 } 1302 // target, if specified 1303 link.setAttribute("target", "_blank"); 1304 if (link.getAttribute("rel") === null) { 1305 link.setAttribute("rel", "noopener"); 1306 } 1307 } 1308 } 1309 function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) { 1310 const config = { 1311 allowHTML: true, 1312 maxWidth: 500, 1313 delay: 100, 1314 arrow: false, 1315 appendTo: function(el) { 1316 return el.parentElement; 1317 }, 1318 interactive: true, 1319 interactiveBorder: 10, 1320 theme: 'quarto', 1321 placement: 'bottom-start', 1322 }; 1323 if (contentFn) { 1324 config.content = contentFn; 1325 } 1326 if (onTriggerFn) { 1327 config.onTrigger = onTriggerFn; 1328 } 1329 if (onUntriggerFn) { 1330 config.onUntrigger = onUntriggerFn; 1331 } 1332 window.tippy(el, config); 1333 } 1334 const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]'); 1335 for (var i=0; i<noterefs.length; i++) { 1336 const ref = noterefs[i]; 1337 tippyHover(ref, function() { 1338 // use id or data attribute instead here 1339 let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href'); 1340 try { href = new URL(href).hash; } catch {} 1341 const id = href.replace(/^#\/?/, ""); 1342 const note = window.document.getElementById(id); 1343 if (note) { 1344 return note.innerHTML; 1345 } else { 1346 return ""; 1347 } 1348 }); 1349 } 1350 const xrefs = window.document.querySelectorAll('a.quarto-xref'); 1351 const processXRef = (id, note) => { 1352 // Strip column container classes 1353 const stripColumnClz = (el) => { 1354 el.classList.remove("page-full", "page-columns"); 1355 if (el.children) { 1356 for (const child of el.children) {
1357 stripColumnClz(child); 1358 } 1359 } 1360 } 1361 stripColumnClz(note) 1362 if (id === null || id.startsWith('sec-')) { 1363 // Special case sections, only their first couple elements 1364 const container = document.createElement("div"); 1365 if (note.children && note.children.length > 2) { 1366 container.appendChild(note.children[0].cloneNode(true)); 1367 for (let i = 1; i < note.children.length; i++) { 1368 const child = note.children[i]; 1369 if (child.tagName === "P" && child.innerText === "") { 1370 continue; 1371 } else { 1372 container.appendChild(child.cloneNode(true)); 1373 break; 1374 } 1375 } 1376 if (window.Quarto?.typesetMath) { 1377 window.Quarto.typesetMath(container); 1378 } 1379 return container.innerHTML 1380 } else { 1381 if (window.Quarto?.typesetMath) { 1382 window.Quarto.typesetMath(note); 1383 } 1384 return note.innerHTML; 1385 } 1386 } else { 1387 // Remove any anchor links if they are present 1388 const anchorLink = note.querySelector('a.anchorjs-link'); 1389 if (anchorLink) { 1390 anchorLink.remove(); 1391 } 1392 if (window.Quarto?.typesetMath) { 1393 window.Quarto.typesetMath(note); 1394 } 1395 if (note.classList.contains("callout")) { 1396 return note.outerHTML; 1397 } else { 1398 return note.innerHTML; 1399 } 1400 } 1401 } 1402 for (var i=0; i<xrefs.length; i++) { 1403 const xref = xrefs[i]; 1404 tippyHover(xref, undefined, function(instance) { 1405 instance.disable(); 1406 let url = xref.getAttribute('href'); 1407 let hash = undefined; 1408 if (url.startsWith('#')) { 1409 hash = url; 1410 } else { 1411 try { hash = new URL(url).hash; } catch {} 1412 } 1413 if (hash) { 1414 const id = hash.replace(/^#\/?/, ""); 1415 const note = window.document.getElementById(id); 1416 if (note !== null) { 1417 try { 1418 const html = processXRef(id, note.cloneNode(true)); 1419 instance.setContent(html); 1420 } finally { 1421 instance.enable(); 1422 instance.show(); 1423 } 1424 } else { 1425 // See if we can fetch this 1426 fetch(url.split('#')[0]) 1427 .then(res => res.text()) 1428 .then(html => { 1429 const parser = new DOMParser(); 1430 const htmlDoc = parser.parseFromString(html, "text/html"); 1431 const note = htmlDoc.getElementById(id); 1432 if (note !== null) { 1433 const html = processXRef(id, note); 1434 instance.setContent(html); 1435 } 1436 }).finally(() => { 1437 instance.enable(); 1438 instance.show(); 1439 }); 1440 } 1441 } else { 1442 // See if we can fetch a full url (with no hash to target) 1443 // This is a special case and we should probably do some content thinning / targeting 1444 fetch(url) 1445 .then(res => res.text()) 1446 .then(html => { 1447 const parser = new DOMParser(); 1448 const htmlDoc = parser.parseFromString(html, "text/html"); 1449 const note = htmlDoc.querySelector('main.content'); 1450 if (note !== null) { 1451 // This should only happen for chapter cross references 1452 // (since there is no id in the URL) 1453 // remove the first header 1454 if (note.children.length > 0 && note.children[0].tagName === "HEADER") { 1455 note.children[0].remove(); 1456 } 1457 const html = processXRef(null, note); 1458 instance.setContent(html); 1459 } 1460 }).finally(() => { 1461 instance.enable(); 1462 instance.show(); 1463 }); 1464 } 1465 }, function(instance) { 1466 }); 1467 } 1468 let selectedAnnoteEl; 1469 const selectorForAnnotation = ( cell, annotation) => { 1470 let cellAttr = 'data-code-cell="' + cell + '"'; 1471 let lineAttr = 'data-code-annotation="' + annotation + '"'; 1472 const selector = 'span[' + cellAttr + '][' + lineAttr + ']'; 1473 return selector; 1474 } 1475 const selectCodeLines = (annoteEl) => { 1476 const doc = window.document; 1477 const targetCell = annoteEl.getAttribute("data-target-cell"); 1478 const targetAnnotation = annoteEl.getAttribute("data-target-annotation"); 1479 const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation)); 1480 const lines = annoteSpan.getAttribute("data-code-lines").split(","); 1481 const lineIds = lines.map((line) => { 1482 return targetCell + "-" + line; 1483 }) 1484 let top = null; 1485 let height = null; 1486 let parent = null; 1487 if (lineIds.length > 0) { 1488 //compute the position of the single el (top and bottom and make a div) 1489 const el = window.document.getElementById(lineIds[0]); 1490 top = el.offsetTop; 1491 height = el.offsetHeight; 1492 parent = el.parentElement.parentElement; 1493 if (lineIds.length > 1) { 1494 const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]); 1495 const bottom = lastEl.offsetTop + lastEl.offsetHeight; 1496 height = bottom - top; 1497 } 1498 if (top !== null && height !== null && parent !== null) { 1499 // cook up a div (if necessary) and position it 1500 let div = window.document.getElementById("code-annotation-line-highlight"); 1501 if (div === null) { 1502 div = window.document.createElement("div"); 1503 div.setAttribute("id", "code-annotation-line-highlight"); 1504 div.style.position = 'absolute'; 1505 parent.appendChild(div); 1506 } 1507 div.style.top = top - 2 + "px"; 1508 div.style.height = height + 4 + "px"; 1509 div.style.left = 0; 1510 let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter"); 1511 if (gutterDiv === null) { 1512 gutterDiv = window.document.createElement("div"); 1513 gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter"); 1514 gutterDiv.style.position = 'absolute'; 1515 const codeCell = window.document.getElementById(targetCell); 1516 const gutter = codeCell.querySelector('.code-annotation-gutter'); 1517 gutter.appendChild(gutterDiv); 1518 } 1519 gutterDiv.style.top = top - 2 + "px"; 1520 gutterDiv.style.height = height + 4 + "px"; 1521 } 1522 selectedAnnoteEl = annoteEl; 1523 } 1524 }; 1525 const unselectCodeLines = () => { 1526 const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"]; 1527 elementsIds.forEach((elId) => { 1528 const div = window.document.getElementById(elId); 1529 if (div) { 1530 div.remove(); 1531 } 1532 }); 1533 selectedAnnoteEl = undefined; 1534 }; 1535 // Handle positioning of the toggle 1536 window.addEventListener( 1537 "resize", 1538 throttle(() => { 1539 elRect = undefined; 1540 if (selectedAnnoteEl) { 1541 selectCodeLines(selectedAnnoteEl); 1542 } 1543 }, 10) 1544 ); 1545 function throttle(fn, ms) { 1546 let throttle = false;
1547 let timer; 1548 return (...args) => { 1549 if(!throttle) { // first call gets through 1550 fn.apply(this, args); 1551 throttle = true; 1552 } else { // all the others get throttled 1553 if(timer) clearTimeout(timer); // cancel #2 1554 timer = setTimeout(() => { 1555 fn.apply(this, args); 1556 timer = throttle = false; 1557 }, ms); 1558 } 1559 }; 1560 } 1561 // Attach click handler to the DT 1562 const annoteDls = window.document.querySelectorAll('dt[data-target-cell]'); 1563 for (const annoteDlNode of annoteDls) { 1564 annoteDlNode.addEventListener('click', (event) => { 1565 const clickedEl = event.target; 1566 if (clickedEl !== selectedAnnoteEl) { 1567 unselectCodeLines(); 1568 const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active'); 1569 if (activeEl) { 1570 activeEl.classList.remove('code-annotation-active'); 1571 } 1572 selectCodeLines(clickedEl); 1573 clickedEl.classList.add('code-annotation-active'); 1574 } else { 1575 // Unselect the line 1576 unselectCodeLines(); 1577 clickedEl.classList.remove('code-annotation-active'); 1578 } 1579 }); 1580 } 1581 const findCites = (el) => { 1582 const parentEl = el.parentElement; 1583 if (parentEl) { 1584 const cites = parentEl.dataset.cites; 1585 if (cites) { 1586 return { 1587 el, 1588 cites: cites.split(' ') 1589 }; 1590 } else { 1591 return findCites(el.parentElement) 1592 } 1593 } else { 1594 return undefined; 1595 } 1596 }; 1597 var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]'); 1598 for (var i=0; i<bibliorefs.length; i++) { 1599 const ref = bibliorefs[i]; 1600 const citeInfo = findCites(ref); 1601 if (citeInfo) { 1602 tippyHover(citeInfo.el, function() { 1603 var popup = window.document.createElement('div'); 1604 citeInfo.cites.forEach(function(cite) { 1605 var citeDiv = window.document.createElement('div'); 1606 citeDiv.classList.add('hanging-indent'); 1607 citeDiv.classList.add('csl-entry'); 1608 var biblioDiv = window.document.getElementById('ref-' + cite); 1609 if (biblioDiv) { 1610 citeDiv.innerHTML = biblioDiv.innerHTML; 1611 } 1612 popup.appendChild(citeDiv); 1613 }); 1614 return popup.innerHTML; 1615 }); 1616 } 1617 } 1618 }); 1619 </script>
1619 1620</div> <!-- /content --> 1621<footer class="footer"> 1622 <div class="nav-footer"> 1623 <div class="nav-footer-left"> 1624 1625 </div> 1626 <div class="nav-footer-center"> 1627<p><a type="button" data-cc="c-settings" class="cc-link">Cookies/analytics preferences</a></p> 1628<div class="toc-actions"><ul><li><a href="https://gitlab.com/declann/calcwithdec.dev/edit/main/posts/pictures-pensions/index.qmd" class="toc-action"><i class="bi bi-git"></i>Edit this page</a></li><li><a href="https://gitlab.com/declann/calcwithdec.dev/blob/main/posts/pictures-pensions/index.qmd" class="toc-action"><i class="bi empty"></i>View source</a></li><li><a href="https://gitlab.com/declann/calcwithdec.dev/-/issues" class="toc-action"><i class="bi empty"></i>Report an issue</a></li></ul></div></div> 1629 <div class="nav-footer-right"> 1630 1631 </div> 1632 </div> 1633</footer>
1634<script defer="" src="../../resources/cookieconsent-2.9.1/dist/cookieconsent.js"></script>
1634 |
1635<script defer="" src="../../cookieconsent-init.js"></script>
vendor: 1 bytes, line 1635
1635
1636<script defer="" type="text/plain" data-cookiecategory="analytics" data-domain="calcwithdec.dev" src="https://plausible.io/js/script.js"></script>
vendor: 1 bytes, line 1636
1636
1637<script>window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>
1637 1638 1639 1640 1641 1642</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.