1<!DOCTYPE html> 2<html><head><meta charset="UTF-8"><meta content="width=device-width, initial-scale=1" name="viewport"><meta content="formform (in its current state) has three core modules:" property="og:description"><meta content="Introduction to formform" property="og:title"><meta content="article:clerk" property="og:type"><meta content="summary_large_image" name="twitter:card">
2<script src="https://cdn.tailwindcss.com?plugins=typography" type="text/javascript"></script>
2<script>tailwind.config = { 3 darkMode: "class", 4 content: ["./tw/viewer.js", "./tw/**/*.edn"], 5 safelist: ['dark'], 6 theme: { 7 extend: {}, 8 fontFamily: { 9 sans: ["Fira Sans", "-apple-system", "BlinkMacSystemFont", "sans-serif"], 10 serif: ["PT Serif", "serif"], 11 mono: ["Fira Mono", "monospace"] 12 } 13 }, 14 variants: { 15 extend: {}, 16 }, 17 plugins: [], 18} 19</script>
19<style type="text/tailwindcss">@tailwind base; 20@tailwind components; 21@tailwind utilities; 22 23@layer base { 24 html { 25 font-size: 18px; 26 } 27 @media (max-width: 600px) { 28 html { 29 font-size: 16px; 30 } 31 } 32 .font-condensed { font-family: "Fira Sans Condensed", sans-serif; } 33 .font-inter { font-family: "Inter", sans-serif; } 34 body { 35 @apply font-serif antialiased text-gray-900 sm:overscroll-y-none pb-8; 36 } 37 code, .code { 38 @apply font-mono text-sm text-gray-900 bg-slate-50 px-0.5 py-px rounded dark:bg-gray-800; 39 } 40 code::before, code::after { @apply content-none !important; } 41 h1, h3, h4, h5, h6 { 42 @apply font-condensed font-bold mt-8 first:mt-0; 43 } 44 h2 { 45 /*We cannot collapse margins due to nesting but we want to*/ 46 /*keep the h2âs large margin visible*/ 47 @apply font-condensed font-bold mt-8 first:mt-2; 48 } 49 h1 { @apply text-4xl; } 50 h2 { @apply text-3xl; } 51 h3 { @apply text-2xl; } 52 53 @media print { 54 h1 { @apply text-2xl !important; } 55 h2 { @apply text-xl !important; } 56 h3 { @apply text-lg !important; } 57 } 58 59 button { @apply focus:outline-none; } 60 strong { @apply font-bold; } 61 em { @apply italic; } 62 pre { @apply m-0 font-mono; } 63 table img { @apply inline-block; } 64} 65 66/* Compatibility */ 67/* --------------------------------------------------------------- */ 68/* TODO: Verify which colors are in use and replace with Tailwind 69 colors accordingly. Move Nj-specific styles out of here. */ 70 71:root { 72 --teal-color: #31afd0; 73 --dark-teal-color: #095960; 74 --near-black-color: #2e2e2c; 75 --red-color: #d64242; 76 --dark-blue-color: #1f2937; 77 --dark-blue-60-color: rgba(28, 42, 56, 0.6); 78 --gray-panel-color: rgba(239, 241, 245, 1.000); 79 --brand-color: var(--dark-blue-color); 80 --link-color: #5046e4; 81 --command-bar-selected-color: var(--teal-color); 82} 83 84.serif { @apply font-serif; } 85.sans-serif { @apply font-sans; } 86.monospace { @apply font-mono; } 87.inter { @apply font-inter; } 88 89.border-color-teal { border-color: var(--dark-teal-color); } 90.teal { color: var(--teal-color); } 91.bg-dark-blue { background: var(--dark-blue-color); } 92.bg-dark-blue-60 { background: rgba(28, 42, 56, 0.6); } 93.bg-gray-panel { background: var(--gray-panel-color); } 94.text-dark-blue { color: var(--dark-blue-color); } 95.text-dark-blue-60 { color: var(--dark-blue-60-color); } 96.border-dark-blue-30 { border-color: rgba(28, 42, 56, 0.6); } 97.text-brand { color: var(--dark-blue-color); } 98.bg-brand { background: var(--dark-blue-color); } 99.text-selected { color: white; } 100.red { color: var(--red-color); } 101 102/* Disclose Button */ 103/* --------------------------------------------------------------- */ 104 105.disclose { 106 @apply content-none border-solid cursor-pointer inline-block relative mr-[3px] top-[-2px] transition-all; 107 border-color: var(--near-black-color) transparent; 108 border-width: 6px 4px 0; 109} 110.disclose:hover { 111 border-color: var(--near-black-color) transparent; 112} 113.dark .disclose, 114.dark .disclose:hover { 115 border-color: white transparent; 116} 117.disclose.collapsed { 118 @apply rotate-[-90deg]; 119} 120 121/* Layout */ 122/* --------------------------------------------------------------- */ 123 124.page { 125 @apply max-w-5xl mx-auto px-12 box-border flex-shrink-0; 126} 127.max-w-prose { @apply max-w-[46rem] !important; } 128.max-w-wide { @apply max-w-3xl !important; } 129 130/* List Styles */ 131/* --------------------------------------------------------------- */ 132 133.task-list-item + .task-list-item, 134.markdown-viewer ul ul { 135 @apply mt-1 mb-0; 136} 137 138/* compact TOC */ 139.markdown-viewer .toc ul { 140 list-style: none; 141 @apply my-1; 142} 143 144/* Code Viewer */ 145/* --------------------------------------------------------------- */ 146 147.code-viewer { 148 @apply font-mono bg-slate-100 rounded-sm text-sm overflow-x-auto dark:bg-gray-800; 149} 150.code-listing { 151 @apply -ml-8 -mr-8 relative !important; 152} 153.code-viewer .cm-content { 154 @apply py-4 px-8; 155} 156@media (min-width: 960px){ 157 .notebook-viewer .code-viewer .cm-content { 158 @apply pl-12; 159 } 160 .notebook-viewer .code-listing { 161 width: 48rem !important; 162 @apply -ml-12 mr-0 !important; 163 } 164} 165/* Donât show focus outline when double-clicking cell in Safari */ 166.cm-scroller { @apply focus:outline-none; } 167 168/* Syntax Highlighting */ 169/* --------------------------------------------------------------- */ 170 171.inspected-value { @apply text-xs font-mono leading-[1.25rem]; } 172.cmt-strong, .cmt-heading { @apply font-bold; }
173.cmt-italic, .cmt-emphasis { @apply italic; } 174.cmt-strikethrough { @apply line-through; } 175.cmt-link { @apply underline; } 176.untyped-value { @apply whitespace-nowrap; } 177 178.cm-editor, .cmt-default, .result-viewer { 179 @apply text-slate-800 dark:text-slate-300; 180} 181.cmt-keyword { 182 @apply text-purple-800 dark:text-pink-400; 183} 184.cmt-atom, .cmt-bool, .cmt-url, .cmt-contentSeparator, .cmt-labelName { 185 @apply text-blue-900 dark:text-blue-300; 186} 187.cmt-inserted, .cmt-literal { 188 @apply text-emerald-700 dark:text-emerald-200; 189} 190.cmt-string, .cmt-deleted { 191 @apply text-rose-700 dark:text-sky-300; 192} 193.cmt-italic.cmt-string { 194 @apply dark:text-sky-200; 195} 196.cmt-regexp, .cmt-escape { 197 @apply text-orange-500 dark:text-orange-300; 198} 199.cmt-variableName { 200 @apply text-blue-800 dark:text-sky-300; 201} 202.cmt-typeName, .cmt-namespace { 203 @apply text-emerald-600 dark:text-emerald-300; 204} 205.cmt-className { 206 @apply text-teal-600 dark:text-teal-200; 207} 208.cmt-macroName { 209 @apply text-teal-700 dark:text-teal-200; 210} 211.cmt-propertyName { 212 @apply text-blue-700 dark:text-blue-200; 213} 214.cmt-comment { 215 @apply text-slate-500 dark:text-slate-400; 216} 217.cmt-meta { 218 @apply text-slate-600 dark:text-slate-400; 219} 220.cmt-invalid { 221 @apply text-red-500 dark:text-red-300; 222} 223 224.result-data { 225 @apply font-mono text-sm overflow-x-auto whitespace-nowrap leading-normal; 226} 227.result-data::-webkit-scrollbar, .path-nav::-webkit-scrollbar {
228 @apply h-0; 229} 230.result-data-collapsed { 231 @apply whitespace-nowrap; 232} 233.result-data-field { 234 @apply ml-4 whitespace-nowrap; 235} 236.result-data-field-link{ 237 @apply ml-4 whitespace-nowrap cursor-pointer; 238} 239.result-data-field-link:hover { 240 @apply text-black bg-black/5; 241} 242.result-text-empty { 243 color: rgba(0,0,0,.3); 244} 245.browsify-button:hover { 246 box-shadow: -2px 0 0 2px #edf2f7; 247} 248 249/* Prose */ 250/* --------------------------------------------------------------- */ 251 252.notebook-viewer, 253.markdown-viewer { 254 @apply prose 255 dark:prose-invert 256 prose-a:text-blue-600 prose-a:no-underline hover:prose-a:underline 257 dark:prose-a:text-blue-300 258 prose-p:mt-4 prose-p:leading-snug 259 prose-ol:mt-4 prose-ol:mb-6 prose-ol:leading-snug 260 prose-ul:mt-4 prose-ul:mb-6 prose-ul:leading-snug 261 prose-blockquote:mt-4 prose-blockquote:leading-snug 262 prose-hr:mt-6 prose-hr:border-t-2 prose-hr:border-solid prose-hr:border-slate-200 263 prose-figure:mt-4 264 prose-figcaption:mt-2 prose-figcaption:text-xs 265 prose-headings:mb-4 266 prose-table:mt-0 267 prose-th:mb-0 268 prose-img:my-0 269 prose-code:font-medium prose-code:bg-slate-100 270 max-w-none; 271} 272.markdown-viewer blockquote p:first-of-type:before, 273.markdown-viewer blockquote p:last-of-type:after { 274 @apply content-none; 275} 276.markdown-node-viewer.result-viewer.fragment-item { 277 @apply mb-0 !important; 278} 279 280figcaption .markdown-viewer { 281 @apply text-xs text-slate-500; 282} 283 284figcaption .markdown-viewer a { 285 @apply underline; 286} 287/* Images */ 288/* --------------------------------------------------------------- */ 289 290 291/* Todo Lists */ 292/* --------------------------------------------------------------- */ 293 294.contains-task-list { 295 @apply pl-6 list-none; 296} 297.contains-task-list input[type="checkbox"] { 298 @apply appearance-none h-4 w-4 rounded border border-slate-200 relative mr-[0.3rem] ml-[-1.5rem] top-[0.15rem]; 299} 300.contains-task-list input[type="checkbox"]:checked { 301 @apply border-indigo-600 bg-indigo-600 bg-no-repeat bg-contain; 302 background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e"); 303} 304 305/* Markdown TOC */ 306/* --------------------------------------------------------------- */ 307 308.markdown-viewer .toc { @apply mt-4; } 309.markdown-viewer h1 + .toc { @apply mt-8; } 310 311.markdown-viewer .toc h1, 312.markdown-viewer .toc h2, 313.markdown-viewer .toc h3, 314.markdown-viewer .toc h4, 315.markdown-viewer .toc h5, 316.markdown-viewer .toc h6 { 317 @apply text-base text-indigo-600 font-sans my-0; 318} 319.markdown-viewer .toc a { 320 @apply text-indigo-600 font-normal no-underline hover:underline; 321} 322.markdown-viewer .toc li { @apply m-0; } 323.markdown-viewer .toc ul ul { @apply pl-4; } 324 325/* Notebook Spacing */ 326/* --------------------------------------------------------------- */ 327 328.markdown-viewer *:first-child:not(.code-viewer):not(li):not(h2):not(.sidenote) { @apply mt-0; } 329/*.viewer + .viewer { @apply mt-6; }*/ 330.viewer + .result-viewer { @apply mt-0; } 331.code-viewer + .result-viewer { @apply mt-3; } 332.markdown-viewer + .markdown-viewer { @apply mt-0; } 333 334/* Sidenotes */ 335/* --------------------------------------------------------------- */ 336 337.sidenote-ref { 338 @apply top-[-0.5em] w-auto h-auto inline border-0 bg-transparent m-0 pointer-events-none; 339} 340.sidenote { 341 @apply block font-sans text-xs mt-4 bg-slate-100 dark:bg-slate-800 p-4; 342 font-style: normal; 343 font-weight: normal; 344} 345.sidenote-container { 346 @apply mb-4; 347} 348.sidenote-main-col *:last-child { 349 @apply mb-0; 350} 351.sidenote-main-col { 352 @apply w-full; 353} 354.sidenote-main-col > ul > li:first-child, 355.sidenote-main-col > ol > li:first-child { 356 @apply mt-0; 357} 358@media (min-width: 860px) { 359 .sidenote sup { @apply inline; } 360 .sidenote-column { 361 @apply w-[165px] -mr-[205px] flex-shrink-0; 362 } 363 .sidenote { 364 @apply bg-transparent dark:bg-transparent p-0; 365 } 366 .sidenote:first-child { 367 @apply mt-1; 368 } 369 .sidenotes-layout .markdown-viewer { 370 @apply pr-[241px]; 371 } 372 .sidenote-container { 373 @apply relative flex justify-between; 374 } 375 .sidenote-container > *:not(.sidenote-column) { 376 margin-right: 40px; 377 } 378 .sidenote:last-of-type { 379 380 } 381 .sidenotes-layout h1 { 382 @apply w-[756px] !important; 383 } 384} 385.code-viewer + .viewer:not(.code-viewer):not(.code-viewer-folded), 386.code-viewer-folded + .viewer:not(.code-viewer):not(.code-viewer-folded), 387.result-viewer:not(.markdown-node-viewer) + .result-viewer { 388 @apply mt-2; 389} 390.code-viewer + .code-viewer-folded { 391 @apply mt-4; 392} 393.result-viewer { 394 @apply leading-tight mb-6; 395} 396.code-viewer.fragment-item.result-viewer { 397 @apply mb-0 !important; 398} 399.result-viewer figure {
400 @apply mt-0 !important; 401} 402@media (min-width: 768px) { 403 .devcard-desc > div { 404 @apply max-w-full m-0; 405 } 406} 407 408/* Command Palette */ 409/* --------------------------------------------------------------- */ 410 411.nj-commands-input { 412 @apply bg-transparent text-white; 413} 414.nj-context-menu-item:hover:not([disabled]) { 415 @apply cursor-pointer; 416 background-color: rgba(255,255,255,.14); 417} 418 419/* Devdocs */ 420/* --------------------------------------------------------------- */ 421 422.logo, .logo-white { 423 @apply block indent-[-999em]; 424 background: url(/images/nextjournal-logo.svg) center center no-repeat; 425} 426.devdocs-body { 427 @apply font-inter; 428} 429 430/* Workarounds */ 431/* --------------------------------------------------------------- */ 432 433/* Fixes vega viewer resizing into infinity */ 434.vega-embed .chart-wrapper { @apply h-auto !important; } 435/* fixes fraction separators being overridden by twâs border-color */ 436.katex * { @apply border-black; } 437 438@media print { 439 .dark-mode-toggle, 440 .toc-toggle { @apply hidden; } 441 .notebook-viewer { @apply pt-0; font-size: 12pt !important; margin-left: 0 !important; } 442 .code-viewer .cm-content, 443 .viewer-code .cm-content { @apply whitespace-pre-wrap !important; overflow: none; } 444 .code-viewer .cm-line { font-size: 12pt !important; } 445 html * { page-break-inside: avoid !important; } 446 .toc-panel { @apply hidden; } 447} 448</style>
448<script src="https://storage.clerk.garden/nextjournal/clerk-assets@3ijeaVdc5TGgRwvmeynCSNH8q7u/viewer.js?immutable=true" type="module"></script>
448<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css" rel="stylesheet" type="text/css"><link href="https://fonts.bunny.net" rel="preconnect"><link href="https://fonts.bunny.net/css?family=fira-mono:400,700%7Cfira-sans:400,400i,500,500i,700,700i%7Cfira-sans-condensed:700,700i%7Cpt-serif:400,400i,700,700i" rel="stylesheet" type="text/css"></head><body class="dark:bg-gray-900"><div id="clerk"></div>
448<script type="module">let viewer = nextjournal.clerk.sci_env 449let state = "{:package :directory, :render-router :fetch-edn, :current-path \"notebooks/introduction\", :resource->url {\"/js/viewer.js\" \"https://storage.clerk.garden/nextjournal/clerk-assets@3ijeaVdc5TGgRwvmeynCSNH8q7u/viewer.js?immutable=true\"}, :index \"notebooks/index.clj\"}".replaceAll('nextjournal.clerk.view/escape-closing-script-tag', 'script') 450viewer.init(viewer.read_string(state)) 451</script>
451<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"ce99fea477754e43bf2a625f7940387d","r":1,"spa":2}' crossorigin="anonymous"></script>
451 452</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.