@@ -64,24 +64,24 @@ export async function loadDocContent(docPath) {
const htmlContent = asciidocEngine.convert(adocContent, {
safe: 'secure',
attributes: {
- 'showtitle': true,
+ showtitle: true,
'source-highlighter': 'highlight.js',
- 'icons': 'font',
- 'sectanchors': true,
- 'idprefix': '',
- 'idseparator': '-'
- }
+ icons: 'font',
+ sectanchors: true,
+ idprefix: '',
+ idseparator: '-',
+ },
})
contentEl.innerHTML = String(htmlContent)
// Auto-expand collapsible sections
- contentEl.querySelectorAll('details').forEach(details => {
+ contentEl.querySelectorAll('details').forEach((details) => {
details.setAttribute('open', '')
})
// Make external links open in new tab
- contentEl.querySelectorAll('a[href^="http"]').forEach(link => {
+ contentEl.querySelectorAll('a[href^="http"]').forEach((link) => {
link.setAttribute('target', '_blank')
link.setAttribute('rel', 'noopener noreferrer')
})
diff --git a/website/src/components/doc-page.test.js b/website/src/components/doc-page.test.js
index 74a603c..7b86b6d 100644
--- a/website/src/components/doc-page.test.js
+++ b/website/src/components/doc-page.test.js
@@ -17,9 +17,10 @@ describe('doc-page', () => {
it('falls back to English when localized document is missing', async () => {
i18n.setLang('de')
- global.fetch
- .mockResolvedValueOnce({ ok: false, status: 404 })
- .mockResolvedValueOnce({ ok: true, text: async () => '= About\n\nlink:https://example.com[Example]' })
+ global.fetch.mockResolvedValueOnce({ ok: false, status: 404 }).mockResolvedValueOnce({
+ ok: true,
+ text: async () => '= About\n\nlink:https://example.com[Example]',
+ })
await loadDocContent('docs/about.adoc')
@@ -37,6 +38,8 @@ describe('doc-page', () => {
await loadDocContent('docs/about.adoc')
- expect(document.getElementById('doc-content').textContent).toContain('Failed to Load Documentation')
+ expect(document.getElementById('doc-content').textContent).toContain(
+ 'Failed to Load Documentation'
+ )
})
})
diff --git a/website/src/i18n.js b/website/src/i18n.js
index 3f57a1e..b936865 100644
--- a/website/src/i18n.js
+++ b/website/src/i18n.js
@@ -8,16 +8,16 @@ const DEFAULT_LANG = 'en'
let currentLang = DEFAULT_LANG
export function applyTranslations() {
- document.querySelectorAll('[data-i18n]').forEach(el => {
+ document.querySelectorAll('[data-i18n]').forEach((el) => {
el.textContent = i18n.t(el.dataset.i18n)
})
- document.querySelectorAll('[data-i18n-placeholder]').forEach(el => {
+ document.querySelectorAll('[data-i18n-placeholder]').forEach((el) => {
el.placeholder = i18n.t(el.dataset.i18nPlaceholder)
})
- document.querySelectorAll('[data-i18n-aria]').forEach(el => {
+ document.querySelectorAll('[data-i18n-aria]').forEach((el) => {
el.setAttribute('aria-label', i18n.t(el.dataset.i18nAria))
})
- document.querySelectorAll('[data-i18n-title]').forEach(el => {
+ document.querySelectorAll('[data-i18n-title]').forEach((el) => {
el.setAttribute('title', i18n.t(el.dataset.i18nTitle))
})
}
diff --git a/website/src/main.js b/website/src/main.js
index 0255224..c0a2444 100644
--- a/website/src/main.js
+++ b/website/src/main.js
@@ -4,7 +4,12 @@ import { initTheme, toggleTheme, currentTheme } from './theme.js'
import { renderHeader } from './components/header.js'
import { renderMain } from './components/main-content.js'
import { renderFooter } from './components/footer.js'
-import { renderCardGrid, initCardGrid, applyCardFilters, updateAnchorCount } from './components/card-grid.js'
+import {
+ renderCardGrid,
+ initCardGrid,
+ applyCardFilters,
+ updateAnchorCount,
+} from './components/card-grid.js'
import { fetchData } from './utils/data-loader.js'
import { buildSearchIndex, isIndexReady, isIndexBuilding } from './utils/search-index.js'
import { initRouter, addRoute } from './utils/router.js'
@@ -25,7 +30,8 @@ window.copyAnchorLink = async function copyAnchorLink(anchorId) {
window.showToast = function showToast(message) {
const toast = document.createElement('div')
- toast.className = 'fixed bottom-4 right-4 bg-green-600 text-white px-4 py-2 rounded-lg shadow-lg z-50 animate-fade-in'
+ toast.className =
+ 'fixed bottom-4 right-4 bg-green-600 text-white px-4 py-2 rounded-lg shadow-lg z-50 animate-fade-in'
toast.textContent = message
document.body.appendChild(toast)
@@ -131,7 +137,8 @@ function renderHomePage() {
console.error('Failed to initialize home page:', err)
const container = document.getElementById('main-content')
if (container) {
- container.innerHTML = '
Failed to load anchors. Please try again later.
'
+ container.innerHTML =
+ '
Failed to load anchors. Please try again later.
'
}
})
}
diff --git a/website/src/styles/asciidoctor-scoped.css b/website/src/styles/asciidoctor-scoped.css
index 7b7c624..8285537 100644
--- a/website/src/styles/asciidoctor-scoped.css
+++ b/website/src/styles/asciidoctor-scoped.css
@@ -10,7 +10,7 @@
/* Base typography */
background: #fff;
color: rgba(0, 0, 0, 0.8);
- font-family: "Noto Serif", "DejaVu Serif", serif;
+ font-family: 'Noto Serif', 'DejaVu Serif', serif;
line-height: 1.6;
& * {
@@ -35,7 +35,7 @@
& h4,
& h5,
& h6 {
- font-family: "Open Sans", "DejaVu Sans", sans-serif;
+ font-family: 'Open Sans', 'DejaVu Sans', sans-serif;
font-weight: 300;
color: #ba3925;
text-rendering: optimizeLegibility;
@@ -44,12 +44,24 @@
line-height: 1.2;
}
- & h1 { font-size: 2.125em; }
- & h2 { font-size: 1.6875em; }
- & h3 { font-size: 1.375em; }
- & h4 { font-size: 1.125em; }
- & h5 { font-size: 1.0625em; }
- & h6 { font-size: 1em; }
+ & h1 {
+ font-size: 2.125em;
+ }
+ & h2 {
+ font-size: 1.6875em;
+ }
+ & h3 {
+ font-size: 1.375em;
+ }
+ & h4 {
+ font-size: 1.125em;
+ }
+ & h5 {
+ font-size: 1.0625em;
+ }
+ & h6 {
+ font-size: 1em;
+ }
& p {
line-height: 1.6;
@@ -60,7 +72,7 @@
& code,
& kbd,
& pre {
- font-family: "Noto Sans Mono", "Droid Sans Mono", monospace;
+ font-family: 'Noto Sans Mono', 'Droid Sans Mono', monospace;
font-size: 1em;
}
diff --git a/website/src/styles/asciidoctor.css b/website/src/styles/asciidoctor.css
index 677db7c..ecb16a9 100644
--- a/website/src/styles/asciidoctor.css
+++ b/website/src/styles/asciidoctor.css
@@ -1,393 +1,1877 @@
/*! Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
/* Uncomment the following line when using as a custom stylesheet */
/* @import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CNoto+Sans+Mono:400,700"; */
-*,::before,::after{box-sizing:border-box}
-html{font-size:100%;-webkit-text-size-adjust:100%}
-body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-size:inherit;line-height:1;position:relative;cursor:auto;-moz-tab-size:4;-o-tab-size:4;tab-size:4;word-wrap:anywhere;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
-dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,p,blockquote,th,td{margin:0;padding:0}
-a{background:none;color:#2156a5;text-decoration:underline;line-height:inherit}
-a:active,a:hover{cursor:pointer;outline:0}
-a:focus{outline:thin dotted}
-a:hover,a:focus{color:#1d4b8f}
-abbr{font-size:.9em}
-abbr[title]{cursor:help;border-bottom:1px dotted #dddddf;text-decoration:none}
-b,strong{font-weight:bold;line-height:inherit}
-strong strong{font-weight:400}
-code,kbd,pre{font-family:"Noto Sans Mono","Droid Sans Mono",monospace;font-size:1em}
-code{font-weight:400;color:rgba(0,0,0,.9)}
-pre{color:rgba(0,0,0,.9);line-height:1.45;text-rendering:optimizeSpeed;white-space:pre-wrap}
-dfn{font-style:italic}
-em,i{font-style:italic;line-height:inherit}
-em em{font-style:normal}
-hr{border:solid #dddddf;border-width:1px 0 0;clear:both;height:0;margin:1.25em 0 1.1875em}
-mark{background:#ff0;color:#000}
-p{line-height:1.6;margin-bottom:1.25rem;text-rendering:optimizeLegibility}
-q{quotes:"\201C" "\201D" "\2018" "\2019"}
-small{font-size:60%;line-height:inherit}
-sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
-sup{top:-.5em}
-sub{bottom:-.25em}
-img,object[type^="image/"],svg{display:inline-block;height:auto;max-width:100%;vertical-align:middle}
-img{border:0;-ms-interpolation-mode:bicubic}
-object{max-width:100%}
-svg:not(:root){overflow:hidden}
-figure{margin:0}
-audio,video{display:inline-block}
-audio:not([controls]){display:none;height:0}
-.left{float:left!important}
-.right{float:right!important}
-.text-left,div.text-left>*{text-align:left!important}
-.text-right,div.text-right>*{text-align:right!important}
-.text-center,div.text-center>*{text-align:center!important}
-.text-justify,div.text-justify>*{text-align:justify!important}
-.hide{display:none}
-.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
-p aside{font-size:.875em;line-height:1.35;font-style:italic}
-h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.2;word-spacing:-.05em}
-h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{color:#e99b8f;line-height:0}
-h1{font-size:2.125em}
-h2{font-size:1.6875em}
-h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
-h4,h5{font-size:1.125em}
-h6{font-size:1em}
-ul,ol,dl{line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
-ul,ol{margin-left:1.5em}
-ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0}
-ul.circle{list-style-type:circle}
-ul.disc{list-style-type:disc}
-ul.square{list-style-type:square}
-ul.circle ul:not([class]),ul.disc ul:not([class]),ul.square ul:not([class]){list-style:inherit}
-ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
-dl dt{margin-bottom:.3125em;font-weight:bold}
-dl dd{margin-bottom:1.25em;margin-left:1.125em}
-blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
-blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
-@media screen and (min-width:768px){h1{font-size:2.75em}
-h2{font-size:2.3125em}
-h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
-h4{font-size:1.4375em}}
-table{background:#fff;border:1px solid #dedede;border-collapse:collapse;border-spacing:0;margin-bottom:1.25em;word-wrap:normal}
-table thead,table tfoot{background:#f7f8f7}
-table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
-table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
-table tr.even,table tr.alt{background:#f8f8f7}
-table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{line-height:1.6}
-h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
-.center{margin-left:auto;margin-right:auto}
-.stretch{width:100%}
-.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:"";display:table}
-.clearfix::after,.float-group::after{clear:both}
-:not(pre).nobreak{word-wrap:normal}
-:not(pre).nowrap{white-space:nowrap}
-:not(pre).pre-wrap{white-space:pre-wrap}
-:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
-pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}
-pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}
-.keyseq{color:rgba(51,51,51,.8)}
-kbd{display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 0 rgba(0,0,0,.2),inset 0 0 0 .1em #fff;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
-.keyseq kbd:first-child{margin-left:0}
-.keyseq kbd:last-child{margin-right:0}
-.menuseq,.menuref{color:#000}
-.menuseq b:not(.caret),.menuref{font-weight:inherit}
-.menuseq{word-spacing:-.02em}
-.menuseq b.caret{font-size:1.25em;line-height:.8}
-.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
-b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
-b.button::before{content:"[";padding:0 3px 0 2px}
-b.button::after{content:"]";padding:0 2px 0 3px}
-p a>code:hover{color:rgba(0,0,0,.9)}
-body>div[id]{margin:0 auto;max-width:62.5em;position:relative;padding-left:.9375em;padding-right:.9375em;width:100%}
-body>div[id]::before,body>div[id]::after,#content #footnotes::before{content:"";display:table;clear:both}
-#content{margin-top:1.25em;margin-bottom:.625em}
-#content::before{content:none}
-#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
-#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
-#header>h1:only-child{border-bottom:1px solid #dddddf;padding-bottom:8px}
-#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap}
-#header .details span:first-child{margin-left:-.125em}
-#header .details span.email a{color:rgba(0,0,0,.85)}
-#header .details br{display:none}
-#header .details br+span::before{content:"\00a0\2013\00a0"}
-#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
-#header .details br+span#revremark::before{content:"\00a0|\00a0"}
-#header #revnumber{text-transform:capitalize}
-#header #revnumber::after{content:"\00a0"}
-#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
-#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
-#toc>ul{margin-left:.125em}
-#toc ul.sectlevel0>li:not([class])>a{font-style:italic}
-#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
-#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
-#toc li{line-height:1.3334;margin-top:.3334em}
-#toc a{text-decoration:none}
-#toc a:active{text-decoration:underline}
-#toctitle{color:#7a2518;font-size:1.2em}
-@media screen and (min-width:768px){#toctitle{font-size:1.375em}
-body.toc2{padding-left:15em;padding-right:0}
-body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
-#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
-#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
-#toc.toc2>ul{font-size:.9em;margin-bottom:0}
-#toc.toc2 ul ul{margin-left:0;padding-left:1em}
-#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
-body.toc2.toc-right{padding-left:0;padding-right:15em}
-body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
-@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
-#toc.toc2{width:20em}
-#toc.toc2 #toctitle{font-size:1.375em}
-#toc.toc2>ul{font-size:.95em}
-#toc.toc2 ul ul{padding-left:1.25em}
-body.toc2.toc-right{padding-left:0;padding-right:20em}}
-#content #toc{border:1px solid #e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;border-radius:4px}
-#footer{max-width:none;background:rgba(0,0,0,.8);padding:1.25em}
-#footer-text{color:hsla(0,0%,100%,.8);line-height:1.44}
-.sect1{padding-bottom:.625em}
-@media screen and (min-width:768px){#content{margin-bottom:1.25em}
-.sect1{padding-bottom:1.25em}}
-.sect1:last-child{padding-bottom:0}
-.sect1+.sect1{border-top:1px solid #e7e7e9}
-#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
-#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
-#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
-#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
-#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
-details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
-details{margin-left:1.25rem}
-details>summary{cursor:pointer;display:block;position:relative;line-height:1.6;margin-bottom:.625rem;outline:none;-webkit-tap-highlight-color:transparent}
-details>summary::-webkit-details-marker{display:none}
-details>summary::before{content:"";border:solid transparent;border-left:solid;border-width:.3em 0 .3em .5em;position:absolute;top:.5em;left:-1.25rem;transform:translateX(15%)}
-details[open]>summary::before{border:solid transparent;border-top:solid;border-width:.5em .3em 0;transform:translateY(15%)}
-details>summary::after{content:"";width:1.25rem;height:1em;position:absolute;top:.3em;left:-1.25rem}
-.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
-table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
-.paragraph.lead>p,#preamble>.sectionbody>[class=paragraph]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
-.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
-.admonitionblock>table td.icon{text-align:center;width:80px}
-.admonitionblock>table td.icon img{max-width:none}
-.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
-.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere}
-.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
-.exampleblock>.content{border:1px solid #e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#fffef7;border-radius:4px;box-shadow:0 1px 4px #e0e0dc}
-.sidebarblock{border:1px solid #dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;border-radius:4px}
-.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
-#content #toc>:first-child,.exampleblock>.content>:first-child,.sidebarblock>.content>:first-child{margin-top:0}
-#content #toc>:last-child,.exampleblock>.content>:last-child,.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
-.literalblock pre,.listingblock>.content>pre{border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em}
-@media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}}
-@media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}}
-.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8}
-.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}
-.listingblock>.content{position:relative}
-.listingblock pre>code{display:block}
-.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}
-.listingblock:hover code[data-lang]::before{display:block}
-.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}
-.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
-.listingblock pre.highlightjs{padding:0}
-.listingblock pre.highlightjs>code{padding:1em;border-radius:4px}
-.listingblock pre.prettyprint{border-width:0}
-.prettyprint{background:#f7f7f8}
-pre.prettyprint .linenums{line-height:1.45;margin-left:2em}
-pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0}
-pre.prettyprint li code[data-lang]::before{opacity:1}
-pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none}
-table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none}
-table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal}
-table.linenotable td.code{padding-left:.75em}
-table.linenotable td.linenos{width:.01%}
-table.linenotable td.linenos,pre.pygments .linenos,pre.rouge .linenos{border-right:1px solid;opacity:.35;padding-right:.5em;-webkit-user-select:none;-moz-user-select:none;user-select:none}
-pre.pygments span.linenos,pre.rouge span.linenos{display:inline-block;margin-right:.75em}
-.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
-.quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em}
-.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
-.quoteblock blockquote{margin:0;padding:0;border:0}
-.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
-.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
-.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
-.verseblock{margin:0 1em 1.25em}
-.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans-serif;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
-.verseblock pre strong{font-weight:400}
-.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
-.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
-.quoteblock .attribution br,.verseblock .attribution br{display:none}
-.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
-.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
-.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
-.quoteblock.abstract{margin:0 1em 1.25em;display:block}
-.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
-.quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
-.quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0}
-.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
-.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;font-size:.85rem;text-align:left;margin-right:0}
-p.tableblock:last-child{margin-bottom:0}
-td.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere}
-td.tableblock>.content>:last-child{margin-bottom:-1.25em}
-table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
-table.grid-all>*>tr>*{border-width:1px}
-table.grid-cols>*>tr>*{border-width:0 1px}
-table.grid-rows>*>tr>*{border-width:1px 0}
-table.frame-all{border-width:1px}
-table.frame-ends{border-width:1px 0}
-table.frame-sides{border-width:0 1px}
-table.frame-none>colgroup+*>:first-child>*,table.frame-sides>colgroup+*>:first-child>*{border-top-width:0}
-table.frame-none>:last-child>:last-child>*,table.frame-sides>:last-child>:last-child>*{border-bottom-width:0}
-table.frame-none>*>tr>:first-child,table.frame-ends>*>tr>:first-child{border-left-width:0}
-table.frame-none>*>tr>:last-child,table.frame-ends>*>tr>:last-child{border-right-width:0}
-table.stripes-all>tbody>tr,table.stripes-odd>tbody>tr:nth-of-type(odd),table.stripes-even>tbody>tr:nth-of-type(even),table.stripes-hover>tbody>tr:hover{background:#f8f8f7}
-th.halign-left,td.halign-left{text-align:left}
-th.halign-right,td.halign-right{text-align:right}
-th.halign-center,td.halign-center{text-align:center}
-th.valign-top,td.valign-top{vertical-align:top}
-th.valign-bottom,td.valign-bottom{vertical-align:bottom}
-th.valign-middle,td.valign-middle{vertical-align:middle}
-table thead th,table tfoot th{font-weight:bold}
-tbody tr th{background:#f7f8f7}
-tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
-p.tableblock>code:only-child{background:none;padding:0}
-p.tableblock{font-size:1em}
-ol{margin-left:1.75em}
-ul li ol{margin-left:1.5em}
-dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
-li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
-ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
-ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
-ul.unstyled,ol.unstyled{margin-left:0}
-li>p:empty:only-child::before{content:"";display:inline-block}
-ul.checklist>li>p:first-child{margin-left:-1em}
-ul.checklist>li>p:first-child>.fa-square-o:first-child,ul.checklist>li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
-ul.checklist>li>p:first-child>input[type=checkbox]:first-child{font:inherit;margin:0 .25em 0 0;padding:0}
-ul.inline{display:flex;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
-ul.inline>li{margin-left:1.25em}
-.unstyled dl dt{font-weight:400;font-style:normal}
-ol.arabic{list-style-type:decimal}
-ol.decimal{list-style-type:decimal-leading-zero}
-ol.loweralpha{list-style-type:lower-alpha}
-ol.upperalpha{list-style-type:upper-alpha}
-ol.lowerroman{list-style-type:lower-roman}
-ol.upperroman{list-style-type:upper-roman}
-ol.lowergreek{list-style-type:lower-greek}
-.hdlist>table,.colist>table{border:0;background:none}
-.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
-td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
-td.hdlist1{font-weight:bold;padding-bottom:1.25em}
-td.hdlist2{word-wrap:anywhere}
-.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
-.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
-.colist td:not([class]):first-child img{max-width:none}
-.colist td:not([class]):last-child{padding:.25em 0}
-.thumb,.th{line-height:0;display:inline-block;border:4px solid #fff;box-shadow:0 0 0 1px #ddd}
-.imageblock.left{margin:.25em .625em 1.25em 0}
-.imageblock.right{margin:.25em 0 1.25em .625em}
-.imageblock>.title{margin-bottom:0}
-.imageblock.thumb,.imageblock.th{border-width:6px}
-.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
-.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
-.image.left{margin-right:.625em}
-.image.right{margin-left:.625em}
-a.image{text-decoration:none;display:inline-block}
-a.image object{pointer-events:none}
-sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
-sup.footnote a,sup.footnoteref a{text-decoration:none}
-sup.footnote a:active,sup.footnoteref a:active,#footnotes .footnote a:first-of-type:active{text-decoration:underline}
-#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
-#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
-#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
-#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
-#footnotes .footnote:last-of-type{margin-bottom:0}
-#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
-div.page-break{display:none}
-div.unbreakable{-moz-column-break-inside:avoid;break-inside:avoid}
-.big{font-size:larger}
-.small{font-size:smaller}
-.underline{text-decoration:underline}
-.overline{text-decoration:overline}
-.line-through{text-decoration:line-through}
-.aqua{color:#00bfbf}
-.aqua-background{background:#00fafa}
-.black{color:#000}
-.black-background{background:#000}
-.blue{color:#0000bf}
-.blue-background{background:#0000fa}
-.fuchsia{color:#bf00bf}
-.fuchsia-background{background:#fa00fa}
-.gray{color:#606060}
-.gray-background{background:#7d7d7d}
-.green{color:#006000}
-.green-background{background:#007d00}
-.lime{color:#00bf00}
-.lime-background{background:#00fa00}
-.maroon{color:#600000}
-.maroon-background{background:#7d0000}
-.navy{color:#000060}
-.navy-background{background:#00007d}
-.olive{color:#606000}
-.olive-background{background:#7d7d00}
-.purple{color:#600060}
-.purple-background{background:#7d007d}
-.red{color:#bf0000}
-.red-background{background:#fa0000}
-.silver{color:#909090}
-.silver-background{background:#bcbcbc}
-.teal{color:#006060}
-.teal-background{background:#007d7d}
-.white{color:#bfbfbf}
-.white-background{background:#fafafa}
-.yellow{color:#bfbf00}
-.yellow-background{background:#fafa00}
-span.icon>.fa{cursor:default}
-a span.icon>.fa{cursor:inherit}
-.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
-.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
-.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
-.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
-.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
-.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
-.conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);border-radius:50%;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
-.conum[data-value] *{color:#fff!important}
-.conum[data-value]+b{display:none}
-.conum[data-value]::after{content:attr(data-value)}
-pre .conum[data-value]{position:relative;top:-.125em}
-b.conum *{color:inherit!important}
-.conum:not([data-value]):empty{display:none}
-dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
-h1,h2,p,td.content,span.alt,summary{letter-spacing:-.01em}
-p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
-p,blockquote,dt,td.content,td.hdlist1,span.alt,summary{font-size:1.0625rem}
-.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
-.print-only{display:none!important}
-@page{margin:1.25cm .75cm}
-@media print{*{box-shadow:none!important;text-shadow:none!important}
-html{font-size:80%}
-a{color:inherit!important;text-decoration:underline!important}
-a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
-a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
-abbr[title]{border-bottom:1px dotted}
-abbr[title]::after{content:" (" attr(title) ")"}
-pre,blockquote,tr,img,object,svg{-moz-column-break-inside:avoid;break-inside:avoid}
-thead{display:table-header-group}
-p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
-h2,h3,#toctitle,.sidebarblock>.content>.title{-moz-column-break-after:avoid;break-after:avoid}
-body>div[id]{max-width:none}
-#toc,.sidebarblock,.exampleblock>.content{background:none!important}
-#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
-body.book #header{text-align:center}
-body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
-body.book #header .details{border:0!important;display:block;padding:0!important}
-body.book #header .details span:first-child{margin-left:0!important}
-body.book #header .details br{display:block}
-body.book #header .details br+span::before{content:none!important}
-body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
-body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{-moz-column-break-before:page;break-before:page}
-.listingblock code[data-lang]::before{display:block}
-div.page-break{display:block;-moz-column-break-after:page;break-after:page}
-#footer{padding:0 .9375em}
-.hide-on-print{display:none!important}
-.print-only{display:block!important}
-.hide-for-print{display:none!important}
-.show-for-print{display:inherit!important}}
-@media amzn-kf8,print{#header>h1:first-child{margin-top:1.25rem}
-.sect1{padding:0!important}
-.sect1+.sect1{border:0}
-#footer{background:none}
-#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
-@media amzn-kf8{body>div[id]{padding:0}}
+*,
+::before,
+::after {
+ box-sizing: border-box;
+}
+html {
+ font-size: 100%;
+ -webkit-text-size-adjust: 100%;
+}
+body {
+ background: #fff;
+ color: rgba(0, 0, 0, 0.8);
+ padding: 0;
+ margin: 0;
+ font-family: 'Noto Serif', 'DejaVu Serif', serif;
+ font-size: inherit;
+ line-height: 1;
+ position: relative;
+ cursor: auto;
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+ word-wrap: anywhere;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-font-smoothing: antialiased;
+}
+dl,
+dt,
+dd,
+ul,
+ol,
+li,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+pre,
+p,
+blockquote,
+th,
+td {
+ margin: 0;
+ padding: 0;
+}
+a {
+ background: none;
+ color: #2156a5;
+ text-decoration: underline;
+ line-height: inherit;
+}
+a:active,
+a:hover {
+ cursor: pointer;
+ outline: 0;
+}
+a:focus {
+ outline: thin dotted;
+}
+a:hover,
+a:focus {
+ color: #1d4b8f;
+}
+abbr {
+ font-size: 0.9em;
+}
+abbr[title] {
+ cursor: help;
+ border-bottom: 1px dotted #dddddf;
+ text-decoration: none;
+}
+b,
+strong {
+ font-weight: bold;
+ line-height: inherit;
+}
+strong strong {
+ font-weight: 400;
+}
+code,
+kbd,
+pre {
+ font-family: 'Noto Sans Mono', 'Droid Sans Mono', monospace;
+ font-size: 1em;
+}
+code {
+ font-weight: 400;
+ color: rgba(0, 0, 0, 0.9);
+}
+pre {
+ color: rgba(0, 0, 0, 0.9);
+ line-height: 1.45;
+ text-rendering: optimizeSpeed;
+ white-space: pre-wrap;
+}
+dfn {
+ font-style: italic;
+}
+em,
+i {
+ font-style: italic;
+ line-height: inherit;
+}
+em em {
+ font-style: normal;
+}
+hr {
+ border: solid #dddddf;
+ border-width: 1px 0 0;
+ clear: both;
+ height: 0;
+ margin: 1.25em 0 1.1875em;
+}
+mark {
+ background: #ff0;
+ color: #000;
+}
+p {
+ line-height: 1.6;
+ margin-bottom: 1.25rem;
+ text-rendering: optimizeLegibility;
+}
+q {
+ quotes: '\201C' '\201D' '\2018' '\2019';
+}
+small {
+ font-size: 60%;
+ line-height: inherit;
+}
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+sup {
+ top: -0.5em;
+}
+sub {
+ bottom: -0.25em;
+}
+img,
+object[type^='image/'],
+svg {
+ display: inline-block;
+ height: auto;
+ max-width: 100%;
+ vertical-align: middle;
+}
+img {
+ border: 0;
+ -ms-interpolation-mode: bicubic;
+}
+object {
+ max-width: 100%;
+}
+svg:not(:root) {
+ overflow: hidden;
+}
+figure {
+ margin: 0;
+}
+audio,
+video {
+ display: inline-block;
+}
+audio:not([controls]) {
+ display: none;
+ height: 0;
+}
+.left {
+ float: left !important;
+}
+.right {
+ float: right !important;
+}
+.text-left,
+div.text-left > * {
+ text-align: left !important;
+}
+.text-right,
+div.text-right > * {
+ text-align: right !important;
+}
+.text-center,
+div.text-center > * {
+ text-align: center !important;
+}
+.text-justify,
+div.text-justify > * {
+ text-align: justify !important;
+}
+.hide {
+ display: none;
+}
+.subheader,
+.admonitionblock td.content > .title,
+.audioblock > .title,
+.exampleblock > .title,
+.imageblock > .title,
+.listingblock > .title,
+.literalblock > .title,
+.stemblock > .title,
+.openblock > .title,
+.paragraph > .title,
+.quoteblock > .title,
+table.tableblock > .title,
+.verseblock > .title,
+.videoblock > .title,
+.dlist > .title,
+.olist > .title,
+.ulist > .title,
+.qlist > .title,
+.hdlist > .title {
+ line-height: 1.45;
+ color: #7a2518;
+ font-weight: 400;
+ margin-top: 0;
+ margin-bottom: 0.25em;
+}
+p aside {
+ font-size: 0.875em;
+ line-height: 1.35;
+ font-style: italic;
+}
+h1,
+h2,
+h3,
+#toctitle,
+.sidebarblock > .content > .title,
+h4,
+h5,
+h6 {
+ font-family: 'Open Sans', 'DejaVu Sans', sans-serif;
+ font-weight: 300;
+ font-style: normal;
+ color: #ba3925;
+ text-rendering: optimizeLegibility;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+ line-height: 1.2;
+ word-spacing: -0.05em;
+}
+h1 small,
+h2 small,
+h3 small,
+#toctitle small,
+.sidebarblock > .content > .title small,
+h4 small,
+h5 small,
+h6 small {
+ color: #e99b8f;
+ line-height: 0;
+}
+h1 {
+ font-size: 2.125em;
+}
+h2 {
+ font-size: 1.6875em;
+}
+h3,
+#toctitle,
+.sidebarblock > .content > .title {
+ font-size: 1.375em;
+}
+h4,
+h5 {
+ font-size: 1.125em;
+}
+h6 {
+ font-size: 1em;
+}
+ul,
+ol,
+dl {
+ line-height: 1.6;
+ margin-bottom: 1.25em;
+ list-style-position: outside;
+ font-family: inherit;
+}
+ul,
+ol {
+ margin-left: 1.5em;
+}
+ul li ul,
+ul li ol {
+ margin-left: 1.25em;
+ margin-bottom: 0;
+}
+ul.circle {
+ list-style-type: circle;
+}
+ul.disc {
+ list-style-type: disc;
+}
+ul.square {
+ list-style-type: square;
+}
+ul.circle ul:not([class]),
+ul.disc ul:not([class]),
+ul.square ul:not([class]) {
+ list-style: inherit;
+}
+ol li ul,
+ol li ol {
+ margin-left: 1.25em;
+ margin-bottom: 0;
+}
+dl dt {
+ margin-bottom: 0.3125em;
+ font-weight: bold;
+}
+dl dd {
+ margin-bottom: 1.25em;
+ margin-left: 1.125em;
+}
+blockquote {
+ margin: 0 0 1.25em;
+ padding: 0.5625em 1.25em 0 1.1875em;
+ border-left: 1px solid #ddd;
+}
+blockquote,
+blockquote p {
+ line-height: 1.6;
+ color: rgba(0, 0, 0, 0.85);
+}
+@media screen and (min-width: 768px) {
+ h1 {
+ font-size: 2.75em;
+ }
+ h2 {
+ font-size: 2.3125em;
+ }
+ h3,
+ #toctitle,
+ .sidebarblock > .content > .title {
+ font-size: 1.6875em;
+ }
+ h4 {
+ font-size: 1.4375em;
+ }
+}
+table {
+ background: #fff;
+ border: 1px solid #dedede;
+ border-collapse: collapse;
+ border-spacing: 0;
+ margin-bottom: 1.25em;
+ word-wrap: normal;
+}
+table thead,
+table tfoot {
+ background: #f7f8f7;
+}
+table thead tr th,
+table thead tr td,
+table tfoot tr th,
+table tfoot tr td {
+ padding: 0.5em 0.625em 0.625em;
+ font-size: inherit;
+ color: rgba(0, 0, 0, 0.8);
+ text-align: left;
+}
+table tr th,
+table tr td {
+ padding: 0.5625em 0.625em;
+ font-size: inherit;
+ color: rgba(0, 0, 0, 0.8);
+}
+table tr.even,
+table tr.alt {
+ background: #f8f8f7;
+}
+table thead tr th,
+table tfoot tr th,
+table tbody tr td,
+table tr td,
+table tfoot tr td {
+ line-height: 1.6;
+}
+h1 strong,
+h2 strong,
+h3 strong,
+#toctitle strong,
+.sidebarblock > .content > .title strong,
+h4 strong,
+h5 strong,
+h6 strong {
+ font-weight: 400;
+}
+.center {
+ margin-left: auto;
+ margin-right: auto;
+}
+.stretch {
+ width: 100%;
+}
+.clearfix::before,
+.clearfix::after,
+.float-group::before,
+.float-group::after {
+ content: '';
+ display: table;
+}
+.clearfix::after,
+.float-group::after {
+ clear: both;
+}
+:not(pre).nobreak {
+ word-wrap: normal;
+}
+:not(pre).nowrap {
+ white-space: nowrap;
+}
+:not(pre).pre-wrap {
+ white-space: pre-wrap;
+}
+:not(pre):not([class^='L']) > code {
+ font-size: 0.9375em;
+ font-style: normal !important;
+ letter-spacing: 0;
+ padding: 0.1em 0.5ex;
+ word-spacing: -0.15em;
+ background: #f7f7f8;
+ border-radius: 4px;
+ line-height: 1.45;
+ text-rendering: optimizeSpeed;
+}
+pre code,
+pre pre {
+ color: inherit;
+ font-size: inherit;
+ line-height: inherit;
+}
+pre.nowrap,
+pre.nowrap pre {
+ white-space: pre;
+ word-wrap: normal;
+}
+.keyseq {
+ color: rgba(51, 51, 51, 0.8);
+}
+kbd {
+ display: inline-block;
+ color: rgba(0, 0, 0, 0.8);
+ font-size: 0.65em;
+ line-height: 1.45;
+ background: #f7f7f7;
+ border: 1px solid #ccc;
+ border-radius: 3px;
+ box-shadow:
+ 0 1px 0 rgba(0, 0, 0, 0.2),
+ inset 0 0 0 0.1em #fff;
+ margin: 0 0.15em;
+ padding: 0.2em 0.5em;
+ vertical-align: middle;
+ position: relative;
+ top: -0.1em;
+ white-space: nowrap;
+}
+.keyseq kbd:first-child {
+ margin-left: 0;
+}
+.keyseq kbd:last-child {
+ margin-right: 0;
+}
+.menuseq,
+.menuref {
+ color: #000;
+}
+.menuseq b:not(.caret),
+.menuref {
+ font-weight: inherit;
+}
+.menuseq {
+ word-spacing: -0.02em;
+}
+.menuseq b.caret {
+ font-size: 1.25em;
+ line-height: 0.8;
+}
+.menuseq i.caret {
+ font-weight: bold;
+ text-align: center;
+ width: 0.45em;
+}
+b.button::before,
+b.button::after {
+ position: relative;
+ top: -1px;
+ font-weight: 400;
+}
+b.button::before {
+ content: '[';
+ padding: 0 3px 0 2px;
+}
+b.button::after {
+ content: ']';
+ padding: 0 2px 0 3px;
+}
+p a > code:hover {
+ color: rgba(0, 0, 0, 0.9);
+}
+body > div[id] {
+ margin: 0 auto;
+ max-width: 62.5em;
+ position: relative;
+ padding-left: 0.9375em;
+ padding-right: 0.9375em;
+ width: 100%;
+}
+body > div[id]::before,
+body > div[id]::after,
+#content #footnotes::before {
+ content: '';
+ display: table;
+ clear: both;
+}
+#content {
+ margin-top: 1.25em;
+ margin-bottom: 0.625em;
+}
+#content::before {
+ content: none;
+}
+#header > h1:first-child {
+ color: rgba(0, 0, 0, 0.85);
+ margin-top: 2.25rem;
+ margin-bottom: 0;
+}
+#header > h1:first-child + #toc {
+ margin-top: 8px;
+ border-top: 1px solid #dddddf;
+}
+#header > h1:only-child {
+ border-bottom: 1px solid #dddddf;
+ padding-bottom: 8px;
+}
+#header .details {
+ border-bottom: 1px solid #dddddf;
+ line-height: 1.45;
+ padding-top: 0.25em;
+ padding-bottom: 0.25em;
+ padding-left: 0.25em;
+ color: rgba(0, 0, 0, 0.6);
+ display: flex;
+ flex-flow: row wrap;
+}
+#header .details span:first-child {
+ margin-left: -0.125em;
+}
+#header .details span.email a {
+ color: rgba(0, 0, 0, 0.85);
+}
+#header .details br {
+ display: none;
+}
+#header .details br + span::before {
+ content: '\00a0\2013\00a0';
+}
+#header .details br + span.author::before {
+ content: '\00a0\22c5\00a0';
+ color: rgba(0, 0, 0, 0.85);
+}
+#header .details br + span#revremark::before {
+ content: '\00a0|\00a0';
+}
+#header #revnumber {
+ text-transform: capitalize;
+}
+#header #revnumber::after {
+ content: '\00a0';
+}
+#content > h1:first-child:not([class]) {
+ color: rgba(0, 0, 0, 0.85);
+ border-bottom: 1px solid #dddddf;
+ padding-bottom: 8px;
+ margin-top: 0;
+ padding-top: 1rem;
+ margin-bottom: 1.25rem;
+}
+#toc {
+ border-bottom: 1px solid #e7e7e9;
+ padding-bottom: 0.5em;
+}
+#toc > ul {
+ margin-left: 0.125em;
+}
+#toc ul.sectlevel0 > li:not([class]) > a {
+ font-style: italic;
+}
+#toc ul.sectlevel0 ul.sectlevel1 {
+ margin: 0.5em 0;
+}
+#toc ul {
+ font-family: 'Open Sans', 'DejaVu Sans', sans-serif;
+ list-style-type: none;
+}
+#toc li {
+ line-height: 1.3334;
+ margin-top: 0.3334em;
+}
+#toc a {
+ text-decoration: none;
+}
+#toc a:active {
+ text-decoration: underline;
+}
+#toctitle {
+ color: #7a2518;
+ font-size: 1.2em;
+}
+@media screen and (min-width: 768px) {
+ #toctitle {
+ font-size: 1.375em;
+ }
+ body.toc2 {
+ padding-left: 15em;
+ padding-right: 0;
+ }
+ body.toc2 #header > h1:nth-last-child(2) {
+ border-bottom: 1px solid #dddddf;
+ padding-bottom: 8px;
+ }
+ #toc.toc2 {
+ margin-top: 0 !important;
+ background: #f8f8f7;
+ position: fixed;
+ width: 15em;
+ left: 0;
+ top: 0;
+ border-right: 1px solid #e7e7e9;
+ border-top-width: 0 !important;
+ border-bottom-width: 0 !important;
+ z-index: 1000;
+ padding: 1.25em 1em;
+ height: 100%;
+ overflow: auto;
+ }
+ #toc.toc2 #toctitle {
+ margin-top: 0;
+ margin-bottom: 0.8rem;
+ font-size: 1.2em;
+ }
+ #toc.toc2 > ul {
+ font-size: 0.9em;
+ margin-bottom: 0;
+ }
+ #toc.toc2 ul ul {
+ margin-left: 0;
+ padding-left: 1em;
+ }
+ #toc.toc2 ul.sectlevel0 ul.sectlevel1 {
+ padding-left: 0;
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+ }
+ body.toc2.toc-right {
+ padding-left: 0;
+ padding-right: 15em;
+ }
+ body.toc2.toc-right #toc.toc2 {
+ border-right-width: 0;
+ border-left: 1px solid #e7e7e9;
+ left: auto;
+ right: 0;
+ }
+}
+@media screen and (min-width: 1280px) {
+ body.toc2 {
+ padding-left: 20em;
+ padding-right: 0;
+ }
+ #toc.toc2 {
+ width: 20em;
+ }
+ #toc.toc2 #toctitle {
+ font-size: 1.375em;
+ }
+ #toc.toc2 > ul {
+ font-size: 0.95em;
+ }
+ #toc.toc2 ul ul {
+ padding-left: 1.25em;
+ }
+ body.toc2.toc-right {
+ padding-left: 0;
+ padding-right: 20em;
+ }
+}
+#content #toc {
+ border: 1px solid #e0e0dc;
+ margin-bottom: 1.25em;
+ padding: 1.25em;
+ background: #f8f8f7;
+ border-radius: 4px;
+}
+#footer {
+ max-width: none;
+ background: rgba(0, 0, 0, 0.8);
+ padding: 1.25em;
+}
+#footer-text {
+ color: hsla(0, 0%, 100%, 0.8);
+ line-height: 1.44;
+}
+.sect1 {
+ padding-bottom: 0.625em;
+}
+@media screen and (min-width: 768px) {
+ #content {
+ margin-bottom: 1.25em;
+ }
+ .sect1 {
+ padding-bottom: 1.25em;
+ }
+}
+.sect1:last-child {
+ padding-bottom: 0;
+}
+.sect1 + .sect1 {
+ border-top: 1px solid #e7e7e9;
+}
+#content h1 > a.anchor,
+h2 > a.anchor,
+h3 > a.anchor,
+#toctitle > a.anchor,
+.sidebarblock > .content > .title > a.anchor,
+h4 > a.anchor,
+h5 > a.anchor,
+h6 > a.anchor {
+ position: absolute;
+ z-index: 1001;
+ width: 1.5ex;
+ margin-left: -1.5ex;
+ display: block;
+ text-decoration: none !important;
+ visibility: hidden;
+ text-align: center;
+ font-weight: 400;
+}
+#content h1 > a.anchor::before,
+h2 > a.anchor::before,
+h3 > a.anchor::before,
+#toctitle > a.anchor::before,
+.sidebarblock > .content > .title > a.anchor::before,
+h4 > a.anchor::before,
+h5 > a.anchor::before,
+h6 > a.anchor::before {
+ content: '\00A7';
+ font-size: 0.85em;
+ display: block;
+ padding-top: 0.1em;
+}
+#content h1:hover > a.anchor,
+#content h1 > a.anchor:hover,
+h2:hover > a.anchor,
+h2 > a.anchor:hover,
+h3:hover > a.anchor,
+#toctitle:hover > a.anchor,
+.sidebarblock > .content > .title:hover > a.anchor,
+h3 > a.anchor:hover,
+#toctitle > a.anchor:hover,
+.sidebarblock > .content > .title > a.anchor:hover,
+h4:hover > a.anchor,
+h4 > a.anchor:hover,
+h5:hover > a.anchor,
+h5 > a.anchor:hover,
+h6:hover > a.anchor,
+h6 > a.anchor:hover {
+ visibility: visible;
+}
+#content h1 > a.link,
+h2 > a.link,
+h3 > a.link,
+#toctitle > a.link,
+.sidebarblock > .content > .title > a.link,
+h4 > a.link,
+h5 > a.link,
+h6 > a.link {
+ color: #ba3925;
+ text-decoration: none;
+}
+#content h1 > a.link:hover,
+h2 > a.link:hover,
+h3 > a.link:hover,
+#toctitle > a.link:hover,
+.sidebarblock > .content > .title > a.link:hover,
+h4 > a.link:hover,
+h5 > a.link:hover,
+h6 > a.link:hover {
+ color: #a53221;
+}
+details,
+.audioblock,
+.imageblock,
+.literalblock,
+.listingblock,
+.stemblock,
+.videoblock {
+ margin-bottom: 1.25em;
+}
+details {
+ margin-left: 1.25rem;
+}
+details > summary {
+ cursor: pointer;
+ display: block;
+ position: relative;
+ line-height: 1.6;
+ margin-bottom: 0.625rem;
+ outline: none;
+ -webkit-tap-highlight-color: transparent;
+}
+details > summary::-webkit-details-marker {
+ display: none;
+}
+details > summary::before {
+ content: '';
+ border: solid transparent;
+ border-left: solid;
+ border-width: 0.3em 0 0.3em 0.5em;
+ position: absolute;
+ top: 0.5em;
+ left: -1.25rem;
+ transform: translateX(15%);
+}
+details[open] > summary::before {
+ border: solid transparent;
+ border-top: solid;
+ border-width: 0.5em 0.3em 0;
+ transform: translateY(15%);
+}
+details > summary::after {
+ content: '';
+ width: 1.25rem;
+ height: 1em;
+ position: absolute;
+ top: 0.3em;
+ left: -1.25rem;
+}
+.admonitionblock td.content > .title,
+.audioblock > .title,
+.exampleblock > .title,
+.imageblock > .title,
+.listingblock > .title,
+.literalblock > .title,
+.stemblock > .title,
+.openblock > .title,
+.paragraph > .title,
+.quoteblock > .title,
+table.tableblock > .title,
+.verseblock > .title,
+.videoblock > .title,
+.dlist > .title,
+.olist > .title,
+.ulist > .title,
+.qlist > .title,
+.hdlist > .title {
+ text-rendering: optimizeLegibility;
+ text-align: left;
+ font-family: 'Noto Serif', 'DejaVu Serif', serif;
+ font-size: 1rem;
+ font-style: italic;
+}
+table.tableblock.fit-content > caption.title {
+ white-space: nowrap;
+ width: 0;
+}
+.paragraph.lead > p,
+#preamble > .sectionbody > [class='paragraph']:first-of-type p {
+ font-size: 1.21875em;
+ line-height: 1.6;
+ color: rgba(0, 0, 0, 0.85);
+}
+.admonitionblock > table {
+ border-collapse: separate;
+ border: 0;
+ background: none;
+ width: 100%;
+}
+.admonitionblock > table td.icon {
+ text-align: center;
+ width: 80px;
+}
+.admonitionblock > table td.icon img {
+ max-width: none;
+}
+.admonitionblock > table td.icon .title {
+ font-weight: bold;
+ font-family: 'Open Sans', 'DejaVu Sans', sans-serif;
+ text-transform: uppercase;
+}
+.admonitionblock > table td.content {
+ padding-left: 1.125em;
+ padding-right: 1.25em;
+ border-left: 1px solid #dddddf;
+ color: rgba(0, 0, 0, 0.6);
+ word-wrap: anywhere;
+}
+.admonitionblock > table td.content > :last-child > :last-child {
+ margin-bottom: 0;
+}
+.exampleblock > .content {
+ border: 1px solid #e0e0dc;
+ margin-bottom: 1.25em;
+ padding: 1.25em;
+ background: #fffef7;
+ border-radius: 4px;
+ box-shadow: 0 1px 4px #e0e0dc;
+}
+.sidebarblock {
+ border: 1px solid #dbdbd6;
+ margin-bottom: 1.25em;
+ padding: 1.25em;
+ background: #f3f3f2;
+ border-radius: 4px;
+}
+.sidebarblock > .content > .title {
+ color: #7a2518;
+ margin-top: 0;
+ text-align: center;
+}
+#content #toc > :first-child,
+.exampleblock > .content > :first-child,
+.sidebarblock > .content > :first-child {
+ margin-top: 0;
+}
+#content #toc > :last-child,
+.exampleblock > .content > :last-child,
+.exampleblock > .content > :last-child > :last-child,
+.exampleblock > .content .olist > ol > li:last-child > :last-child,
+.exampleblock > .content .ulist > ul > li:last-child > :last-child,
+.exampleblock > .content .qlist > ol > li:last-child > :last-child,
+.sidebarblock > .content > :last-child,
+.sidebarblock > .content > :last-child > :last-child,
+.sidebarblock > .content .olist > ol > li:last-child > :last-child,
+.sidebarblock > .content .ulist > ul > li:last-child > :last-child,
+.sidebarblock > .content .qlist > ol > li:last-child > :last-child {
+ margin-bottom: 0;
+}
+.literalblock pre,
+.listingblock > .content > pre {
+ border-radius: 4px;
+ overflow-x: auto;
+ padding: 1em;
+ font-size: 0.8125em;
+}
+@media screen and (min-width: 768px) {
+ .literalblock pre,
+ .listingblock > .content > pre {
+ font-size: 0.90625em;
+ }
+}
+@media screen and (min-width: 1280px) {
+ .literalblock pre,
+ .listingblock > .content > pre {
+ font-size: 1em;
+ }
+}
+.literalblock pre,
+.listingblock > .content > pre:not(.highlight),
+.listingblock > .content > pre[class='highlight'],
+.listingblock > .content > pre[class^='highlight '] {
+ background: #f7f7f8;
+}
+.literalblock.output pre {
+ color: #f7f7f8;
+ background: rgba(0, 0, 0, 0.9);
+}
+.listingblock > .content {
+ position: relative;
+}
+.listingblock pre > code {
+ display: block;
+}
+.listingblock code[data-lang]::before {
+ display: none;
+ content: attr(data-lang);
+ position: absolute;
+ font-size: 0.75em;
+ top: 0.425rem;
+ right: 0.5rem;
+ line-height: 1;
+ text-transform: uppercase;
+ color: inherit;
+ opacity: 0.5;
+}
+.listingblock:hover code[data-lang]::before {
+ display: block;
+}
+.listingblock.terminal pre .command::before {
+ content: attr(data-prompt);
+ padding-right: 0.5em;
+ color: inherit;
+ opacity: 0.5;
+}
+.listingblock.terminal pre .command:not([data-prompt])::before {
+ content: '$';
+}
+.listingblock pre.highlightjs {
+ padding: 0;
+}
+.listingblock pre.highlightjs > code {
+ padding: 1em;
+ border-radius: 4px;
+}
+.listingblock pre.prettyprint {
+ border-width: 0;
+}
+.prettyprint {
+ background: #f7f7f8;
+}
+pre.prettyprint .linenums {
+ line-height: 1.45;
+ margin-left: 2em;
+}
+pre.prettyprint li {
+ background: none;
+ list-style-type: inherit;
+ padding-left: 0;
+}
+pre.prettyprint li code[data-lang]::before {
+ opacity: 1;
+}
+pre.prettyprint li:not(:first-child) code[data-lang]::before {
+ display: none;
+}
+table.linenotable {
+ border-collapse: separate;
+ border: 0;
+ margin-bottom: 0;
+ background: none;
+}
+table.linenotable td[class] {
+ color: inherit;
+ vertical-align: top;
+ padding: 0;
+ line-height: inherit;
+ white-space: normal;
+}
+table.linenotable td.code {
+ padding-left: 0.75em;
+}
+table.linenotable td.linenos {
+ width: 0.01%;
+}
+table.linenotable td.linenos,
+pre.pygments .linenos,
+pre.rouge .linenos {
+ border-right: 1px solid;
+ opacity: 0.35;
+ padding-right: 0.5em;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+}
+pre.pygments span.linenos,
+pre.rouge span.linenos {
+ display: inline-block;
+ margin-right: 0.75em;
+}
+.quoteblock {
+ margin: 0 1em 1.25em 1.5em;
+ display: table;
+}
+.quoteblock:not(.excerpt) > .title {
+ margin-left: -1.5em;
+ margin-bottom: 0.75em;
+}
+.quoteblock blockquote,
+.quoteblock p {
+ color: rgba(0, 0, 0, 0.85);
+ font-size: 1.15rem;
+ line-height: 1.75;
+ word-spacing: 0.1em;
+ letter-spacing: 0;
+ font-style: italic;
+ text-align: justify;
+}
+.quoteblock blockquote {
+ margin: 0;
+ padding: 0;
+ border: 0;
+}
+.quoteblock blockquote::before {
+ content: '\201c';
+ float: left;
+ font-size: 2.75em;
+ font-weight: bold;
+ line-height: 0.6em;
+ margin-left: -0.6em;
+ color: #7a2518;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
+}
+.quoteblock blockquote > .paragraph:last-child p {
+ margin-bottom: 0;
+}
+.quoteblock .attribution {
+ margin-top: 0.75em;
+ margin-right: 0.5ex;
+ text-align: right;
+}
+.verseblock {
+ margin: 0 1em 1.25em;
+}
+.verseblock pre {
+ font-family: 'Open Sans', 'DejaVu Sans', sans-serif;
+ font-size: 1.15rem;
+ color: rgba(0, 0, 0, 0.85);
+ font-weight: 300;
+ text-rendering: optimizeLegibility;
+}
+.verseblock pre strong {
+ font-weight: 400;
+}
+.verseblock .attribution {
+ margin-top: 1.25rem;
+ margin-left: 0.5ex;
+}
+.quoteblock .attribution,
+.verseblock .attribution {
+ font-size: 0.9375em;
+ line-height: 1.45;
+ font-style: italic;
+}
+.quoteblock .attribution br,
+.verseblock .attribution br {
+ display: none;
+}
+.quoteblock .attribution cite,
+.verseblock .attribution cite {
+ display: block;
+ letter-spacing: -0.025em;
+ color: rgba(0, 0, 0, 0.6);
+}
+.quoteblock.abstract blockquote::before,
+.quoteblock.excerpt blockquote::before,
+.quoteblock .quoteblock blockquote::before {
+ display: none;
+}
+.quoteblock.abstract blockquote,
+.quoteblock.abstract p,
+.quoteblock.excerpt blockquote,
+.quoteblock.excerpt p,
+.quoteblock .quoteblock blockquote,
+.quoteblock .quoteblock p {
+ line-height: 1.6;
+ word-spacing: 0;
+}
+.quoteblock.abstract {
+ margin: 0 1em 1.25em;
+ display: block;
+}
+.quoteblock.abstract > .title {
+ margin: 0 0 0.375em;
+ font-size: 1.15em;
+ text-align: center;
+}
+.quoteblock.excerpt > blockquote,
+.quoteblock .quoteblock {
+ padding: 0 0 0.25em 1em;
+ border-left: 0.25em solid #dddddf;
+}
+.quoteblock.excerpt,
+.quoteblock .quoteblock {
+ margin-left: 0;
+}
+.quoteblock.excerpt blockquote,
+.quoteblock.excerpt p,
+.quoteblock .quoteblock blockquote,
+.quoteblock .quoteblock p {
+ color: inherit;
+ font-size: 1.0625rem;
+}
+.quoteblock.excerpt .attribution,
+.quoteblock .quoteblock .attribution {
+ color: inherit;
+ font-size: 0.85rem;
+ text-align: left;
+ margin-right: 0;
+}
+p.tableblock:last-child {
+ margin-bottom: 0;
+}
+td.tableblock > .content {
+ margin-bottom: 1.25em;
+ word-wrap: anywhere;
+}
+td.tableblock > .content > :last-child {
+ margin-bottom: -1.25em;
+}
+table.tableblock,
+th.tableblock,
+td.tableblock {
+ border: 0 solid #dedede;
+}
+table.grid-all > * > tr > * {
+ border-width: 1px;
+}
+table.grid-cols > * > tr > * {
+ border-width: 0 1px;
+}
+table.grid-rows > * > tr > * {
+ border-width: 1px 0;
+}
+table.frame-all {
+ border-width: 1px;
+}
+table.frame-ends {
+ border-width: 1px 0;
+}
+table.frame-sides {
+ border-width: 0 1px;
+}
+table.frame-none > colgroup + * > :first-child > *,
+table.frame-sides > colgroup + * > :first-child > * {
+ border-top-width: 0;
+}
+table.frame-none > :last-child > :last-child > *,
+table.frame-sides > :last-child > :last-child > * {
+ border-bottom-width: 0;
+}
+table.frame-none > * > tr > :first-child,
+table.frame-ends > * > tr > :first-child {
+ border-left-width: 0;
+}
+table.frame-none > * > tr > :last-child,
+table.frame-ends > * > tr > :last-child {
+ border-right-width: 0;
+}
+table.stripes-all > tbody > tr,
+table.stripes-odd > tbody > tr:nth-of-type(odd),
+table.stripes-even > tbody > tr:nth-of-type(even),
+table.stripes-hover > tbody > tr:hover {
+ background: #f8f8f7;
+}
+th.halign-left,
+td.halign-left {
+ text-align: left;
+}
+th.halign-right,
+td.halign-right {
+ text-align: right;
+}
+th.halign-center,
+td.halign-center {
+ text-align: center;
+}
+th.valign-top,
+td.valign-top {
+ vertical-align: top;
+}
+th.valign-bottom,
+td.valign-bottom {
+ vertical-align: bottom;
+}
+th.valign-middle,
+td.valign-middle {
+ vertical-align: middle;
+}
+table thead th,
+table tfoot th {
+ font-weight: bold;
+}
+tbody tr th {
+ background: #f7f8f7;
+}
+tbody tr th,
+tbody tr th p,
+tfoot tr th,
+tfoot tr th p {
+ color: rgba(0, 0, 0, 0.8);
+ font-weight: bold;
+}
+p.tableblock > code:only-child {
+ background: none;
+ padding: 0;
+}
+p.tableblock {
+ font-size: 1em;
+}
+ol {
+ margin-left: 1.75em;
+}
+ul li ol {
+ margin-left: 1.5em;
+}
+dl dd:last-child,
+dl dd:last-child > :last-child {
+ margin-bottom: 0;
+}
+li p,
+ul dd,
+ol dd,
+.olist .olist,
+.ulist .ulist,
+.ulist .olist,
+.olist .ulist {
+ margin-bottom: 0.625em;
+}
+ul.checklist,
+ul.none,
+ol.none,
+ul.no-bullet,
+ol.no-bullet,
+ol.unnumbered,
+ul.unstyled,
+ol.unstyled {
+ list-style-type: none;
+}
+ul.no-bullet,
+ol.no-bullet,
+ol.unnumbered {
+ margin-left: 0.625em;
+}
+ul.unstyled,
+ol.unstyled {
+ margin-left: 0;
+}
+li > p:empty:only-child::before {
+ content: '';
+ display: inline-block;
+}
+ul.checklist > li > p:first-child {
+ margin-left: -1em;
+}
+ul.checklist > li > p:first-child > .fa-square-o:first-child,
+ul.checklist > li > p:first-child > .fa-check-square-o:first-child {
+ width: 1.25em;
+ font-size: 0.8em;
+ position: relative;
+ bottom: 0.125em;
+}
+ul.checklist > li > p:first-child > input[type='checkbox']:first-child {
+ font: inherit;
+ margin: 0 0.25em 0 0;
+ padding: 0;
+}
+ul.inline {
+ display: flex;
+ flex-flow: row wrap;
+ list-style: none;
+ margin: 0 0 0.625em -1.25em;
+}
+ul.inline > li {
+ margin-left: 1.25em;
+}
+.unstyled dl dt {
+ font-weight: 400;
+ font-style: normal;
+}
+ol.arabic {
+ list-style-type: decimal;
+}
+ol.decimal {
+ list-style-type: decimal-leading-zero;
+}
+ol.loweralpha {
+ list-style-type: lower-alpha;
+}
+ol.upperalpha {
+ list-style-type: upper-alpha;
+}
+ol.lowerroman {
+ list-style-type: lower-roman;
+}
+ol.upperroman {
+ list-style-type: upper-roman;
+}
+ol.lowergreek {
+ list-style-type: lower-greek;
+}
+.hdlist > table,
+.colist > table {
+ border: 0;
+ background: none;
+}
+.hdlist > table > tbody > tr,
+.colist > table > tbody > tr {
+ background: none;
+}
+td.hdlist1,
+td.hdlist2 {
+ vertical-align: top;
+ padding: 0 0.625em;
+}
+td.hdlist1 {
+ font-weight: bold;
+ padding-bottom: 1.25em;
+}
+td.hdlist2 {
+ word-wrap: anywhere;
+}
+.literalblock + .colist,
+.listingblock + .colist {
+ margin-top: -0.5em;
+}
+.colist td:not([class]):first-child {
+ padding: 0.4em 0.75em 0;
+ line-height: 1;
+ vertical-align: top;
+}
+.colist td:not([class]):first-child img {
+ max-width: none;
+}
+.colist td:not([class]):last-child {
+ padding: 0.25em 0;
+}
+.thumb,
+.th {
+ line-height: 0;
+ display: inline-block;
+ border: 4px solid #fff;
+ box-shadow: 0 0 0 1px #ddd;
+}
+.imageblock.left {
+ margin: 0.25em 0.625em 1.25em 0;
+}
+.imageblock.right {
+ margin: 0.25em 0 1.25em 0.625em;
+}
+.imageblock > .title {
+ margin-bottom: 0;
+}
+.imageblock.thumb,
+.imageblock.th {
+ border-width: 6px;
+}
+.imageblock.thumb > .title,
+.imageblock.th > .title {
+ padding: 0 0.125em;
+}
+.image.left,
+.image.right {
+ margin-top: 0.25em;
+ margin-bottom: 0.25em;
+ display: inline-block;
+ line-height: 0;
+}
+.image.left {
+ margin-right: 0.625em;
+}
+.image.right {
+ margin-left: 0.625em;
+}
+a.image {
+ text-decoration: none;
+ display: inline-block;
+}
+a.image object {
+ pointer-events: none;
+}
+sup.footnote,
+sup.footnoteref {
+ font-size: 0.875em;
+ position: static;
+ vertical-align: super;
+}
+sup.footnote a,
+sup.footnoteref a {
+ text-decoration: none;
+}
+sup.footnote a:active,
+sup.footnoteref a:active,
+#footnotes .footnote a:first-of-type:active {
+ text-decoration: underline;
+}
+#footnotes {
+ padding-top: 0.75em;
+ padding-bottom: 0.75em;
+ margin-bottom: 0.625em;
+}
+#footnotes hr {
+ width: 20%;
+ min-width: 6.25em;
+ margin: -0.25em 0 0.75em;
+ border-width: 1px 0 0;
+}
+#footnotes .footnote {
+ padding: 0 0.375em 0 0.225em;
+ line-height: 1.3334;
+ font-size: 0.875em;
+ margin-left: 1.2em;
+ margin-bottom: 0.2em;
+}
+#footnotes .footnote a:first-of-type {
+ font-weight: bold;
+ text-decoration: none;
+ margin-left: -1.05em;
+}
+#footnotes .footnote:last-of-type {
+ margin-bottom: 0;
+}
+#content #footnotes {
+ margin-top: -0.625em;
+ margin-bottom: 0;
+ padding: 0.75em 0;
+}
+div.page-break {
+ display: none;
+}
+div.unbreakable {
+ -moz-column-break-inside: avoid;
+ break-inside: avoid;
+}
+.big {
+ font-size: larger;
+}
+.small {
+ font-size: smaller;
+}
+.underline {
+ text-decoration: underline;
+}
+.overline {
+ text-decoration: overline;
+}
+.line-through {
+ text-decoration: line-through;
+}
+.aqua {
+ color: #00bfbf;
+}
+.aqua-background {
+ background: #00fafa;
+}
+.black {
+ color: #000;
+}
+.black-background {
+ background: #000;
+}
+.blue {
+ color: #0000bf;
+}
+.blue-background {
+ background: #0000fa;
+}
+.fuchsia {
+ color: #bf00bf;
+}
+.fuchsia-background {
+ background: #fa00fa;
+}
+.gray {
+ color: #606060;
+}
+.gray-background {
+ background: #7d7d7d;
+}
+.green {
+ color: #006000;
+}
+.green-background {
+ background: #007d00;
+}
+.lime {
+ color: #00bf00;
+}
+.lime-background {
+ background: #00fa00;
+}
+.maroon {
+ color: #600000;
+}
+.maroon-background {
+ background: #7d0000;
+}
+.navy {
+ color: #000060;
+}
+.navy-background {
+ background: #00007d;
+}
+.olive {
+ color: #606000;
+}
+.olive-background {
+ background: #7d7d00;
+}
+.purple {
+ color: #600060;
+}
+.purple-background {
+ background: #7d007d;
+}
+.red {
+ color: #bf0000;
+}
+.red-background {
+ background: #fa0000;
+}
+.silver {
+ color: #909090;
+}
+.silver-background {
+ background: #bcbcbc;
+}
+.teal {
+ color: #006060;
+}
+.teal-background {
+ background: #007d7d;
+}
+.white {
+ color: #bfbfbf;
+}
+.white-background {
+ background: #fafafa;
+}
+.yellow {
+ color: #bfbf00;
+}
+.yellow-background {
+ background: #fafa00;
+}
+span.icon > .fa {
+ cursor: default;
+}
+a span.icon > .fa {
+ cursor: inherit;
+}
+.admonitionblock td.icon [class^='fa icon-'] {
+ font-size: 2.5em;
+ text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
+ cursor: default;
+}
+.admonitionblock td.icon .icon-note::before {
+ content: '\f05a';
+ color: #19407c;
+}
+.admonitionblock td.icon .icon-tip::before {
+ content: '\f0eb';
+ text-shadow: 1px 1px 2px rgba(155, 155, 0, 0.8);
+ color: #111;
+}
+.admonitionblock td.icon .icon-warning::before {
+ content: '\f071';
+ color: #bf6900;
+}
+.admonitionblock td.icon .icon-caution::before {
+ content: '\f06d';
+ color: #bf3400;
+}
+.admonitionblock td.icon .icon-important::before {
+ content: '\f06a';
+ color: #bf0000;
+}
+.conum[data-value] {
+ display: inline-block;
+ color: #fff !important;
+ background: rgba(0, 0, 0, 0.8);
+ border-radius: 50%;
+ text-align: center;
+ font-size: 0.75em;
+ width: 1.67em;
+ height: 1.67em;
+ line-height: 1.67em;
+ font-family: 'Open Sans', 'DejaVu Sans', sans-serif;
+ font-style: normal;
+ font-weight: bold;
+}
+.conum[data-value] * {
+ color: #fff !important;
+}
+.conum[data-value] + b {
+ display: none;
+}
+.conum[data-value]::after {
+ content: attr(data-value);
+}
+pre .conum[data-value] {
+ position: relative;
+ top: -0.125em;
+}
+b.conum * {
+ color: inherit !important;
+}
+.conum:not([data-value]):empty {
+ display: none;
+}
+dt,
+th.tableblock,
+td.content,
+div.footnote {
+ text-rendering: optimizeLegibility;
+}
+h1,
+h2,
+p,
+td.content,
+span.alt,
+summary {
+ letter-spacing: -0.01em;
+}
+p strong,
+td.content strong,
+div.footnote strong {
+ letter-spacing: -0.005em;
+}
+p,
+blockquote,
+dt,
+td.content,
+td.hdlist1,
+span.alt,
+summary {
+ font-size: 1.0625rem;
+}
+.sidebarblock p,
+.sidebarblock dt,
+.sidebarblock td.content,
+p.tableblock {
+ font-size: 1em;
+}
+.print-only {
+ display: none !important;
+}
+@page {
+ margin: 1.25cm 0.75cm;
+}
+@media print {
+ * {
+ box-shadow: none !important;
+ text-shadow: none !important;
+ }
+ html {
+ font-size: 80%;
+ }
+ a {
+ color: inherit !important;
+ text-decoration: underline !important;
+ }
+ a.bare,
+ a[href^='#'],
+ a[href^='mailto:'] {
+ text-decoration: none !important;
+ }
+ a[href^='http:']:not(.bare)::after,
+ a[href^='https:']:not(.bare)::after {
+ content: '(' attr(href) ')';
+ display: inline-block;
+ font-size: 0.875em;
+ padding-left: 0.25em;
+ }
+ abbr[title] {
+ border-bottom: 1px dotted;
+ }
+ abbr[title]::after {
+ content: ' (' attr(title) ')';
+ }
+ pre,
+ blockquote,
+ tr,
+ img,
+ object,
+ svg {
+ -moz-column-break-inside: avoid;
+ break-inside: avoid;
+ }
+ thead {
+ display: table-header-group;
+ }
+ p,
+ blockquote,
+ dt,
+ td.content {
+ font-size: 1em;
+ orphans: 3;
+ widows: 3;
+ }
+ h2,
+ h3,
+ #toctitle,
+ .sidebarblock > .content > .title {
+ -moz-column-break-after: avoid;
+ break-after: avoid;
+ }
+ body > div[id] {
+ max-width: none;
+ }
+ #toc,
+ .sidebarblock,
+ .exampleblock > .content {
+ background: none !important;
+ }
+ #toc {
+ border-bottom: 1px solid #dddddf !important;
+ padding-bottom: 0 !important;
+ }
+ body.book #header {
+ text-align: center;
+ }
+ body.book #header > h1:first-child {
+ border: 0 !important;
+ margin: 2.5em 0 1em;
+ }
+ body.book #header .details {
+ border: 0 !important;
+ display: block;
+ padding: 0 !important;
+ }
+ body.book #header .details span:first-child {
+ margin-left: 0 !important;
+ }
+ body.book #header .details br {
+ display: block;
+ }
+ body.book #header .details br + span::before {
+ content: none !important;
+ }
+ body.book #toc {
+ border: 0 !important;
+ text-align: left !important;
+ padding: 0 !important;
+ margin: 0 !important;
+ }
+ body.book #toc,
+ body.book #preamble,
+ body.book h1.sect0,
+ body.book .sect1 > h2 {
+ -moz-column-break-before: page;
+ break-before: page;
+ }
+ .listingblock code[data-lang]::before {
+ display: block;
+ }
+ div.page-break {
+ display: block;
+ -moz-column-break-after: page;
+ break-after: page;
+ }
+ #footer {
+ padding: 0 0.9375em;
+ }
+ .hide-on-print {
+ display: none !important;
+ }
+ .print-only {
+ display: block !important;
+ }
+ .hide-for-print {
+ display: none !important;
+ }
+ .show-for-print {
+ display: inherit !important;
+ }
+}
+@media amzn-kf8, print {
+ #header > h1:first-child {
+ margin-top: 1.25rem;
+ }
+ .sect1 {
+ padding: 0 !important;
+ }
+ .sect1 + .sect1 {
+ border: 0;
+ }
+ #footer {
+ background: none;
+ }
+ #footer-text {
+ color: rgba(0, 0, 0, 0.6);
+ font-size: 0.9em;
+ }
+}
+@media amzn-kf8 {
+ body > div[id] {
+ padding: 0;
+ }
+}
diff --git a/website/src/styles/main.css b/website/src/styles/main.css
index 03cae68..fbe6233 100644
--- a/website/src/styles/main.css
+++ b/website/src/styles/main.css
@@ -1,5 +1,5 @@
-@import "tailwindcss";
-@import "./asciidoctor-scoped.css";
+@import 'tailwindcss';
+@import './asciidoctor-scoped.css';
/* Configure Tailwind v4 dark mode to use class strategy */
@variant dark (.dark &);
@@ -26,16 +26,21 @@
body {
margin: 0;
- font-family: Inter, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
+ font-family: Inter, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
background-color: var(--color-bg);
color: var(--color-text);
- transition: background-color 0.3s ease, color 0.3s ease;
+ transition:
+ background-color 0.3s ease,
+ color 0.3s ease;
}
*,
*::before,
*::after {
- transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
+ transition:
+ background-color 0.3s ease,
+ color 0.3s ease,
+ border-color 0.3s ease;
}
#app {
@@ -47,7 +52,7 @@ body {
/* Card Grid Styles */
.card-grid-container {
@apply max-w-7xl mx-auto px-4 py-8;
- font-family: Inter, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
+ font-family: Inter, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}
#page-content,
@@ -57,7 +62,7 @@ body {
.anchor-card-meta,
.anchor-card-proponents,
.category-heading {
- font-family: Inter, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
+ font-family: Inter, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}
/* Force sans-serif on all card descendants to override AsciiDoc serif fonts */
@@ -67,14 +72,14 @@ body {
.card-grid-container *,
.anchor-cards-grid,
.anchor-cards-grid * {
- font-family: Inter, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !important;
+ font-family: Inter, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif !important;
}
.category-section {
@apply mb-12;
}
-.category-section[style*="display: none"] {
+.category-section[style*='display: none'] {
@apply hidden;
}
@@ -84,7 +89,7 @@ body {
}
/* Ensure category name is visible in dark mode */
-.category-heading span[data-i18n^="categories."] {
+.category-heading span[data-i18n^='categories.'] {
@apply text-gray-900 dark:text-gray-100;
}
diff --git a/website/src/utils/data-loader.js b/website/src/utils/data-loader.js
index 297b2a3..0d40463 100644
--- a/website/src/utils/data-loader.js
+++ b/website/src/utils/data-loader.js
@@ -1,7 +1,19 @@
const CATEGORY_PALETTE = [
- '#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de',
- '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc', '#48b8d0',
- '#c23531', '#2f4554', '#61a0a8', '#d48265', '#749f83'
+ '#5470c6',
+ '#91cc75',
+ '#fac858',
+ '#ee6666',
+ '#73c0de',
+ '#3ba272',
+ '#fc8452',
+ '#9a60b4',
+ '#ea7ccc',
+ '#48b8d0',
+ '#c23531',
+ '#2f4554',
+ '#61a0a8',
+ '#d48265',
+ '#749f83',
]
export function getCategoryColor(index) {
@@ -9,32 +21,32 @@ export function getCategoryColor(index) {
}
export function buildTreemapData(categories, anchors) {
- const anchorMap = new Map(anchors.map(a => [a.id, a]))
+ const anchorMap = new Map(anchors.map((a) => [a.id, a]))
return categories.map((category, index) => {
const children = category.anchors
- .map(anchorId => anchorMap.get(anchorId))
+ .map((anchorId) => anchorMap.get(anchorId))
.filter(Boolean)
- .map(anchor => ({
+ .map((anchor) => ({
id: anchor.id,
name: anchor.title,
value: 1,
roles: anchor.roles || [],
- categoryId: category.id
+ categoryId: category.id,
}))
return {
name: category.name,
id: category.id,
children,
- itemStyle: { color: getCategoryColor(index) }
+ itemStyle: { color: getCategoryColor(index) },
}
})
}
export function getAnchorsByRole(anchors, roleId) {
if (!roleId) return anchors
- return anchors.filter(a => a.roles && a.roles.includes(roleId))
+ return anchors.filter((a) => a.roles && a.roles.includes(roleId))
}
export function getAnchorsBySearch(anchors, query) {
@@ -42,11 +54,13 @@ export function getAnchorsBySearch(anchors, query) {
const lowerQuery = query.toLowerCase().trim()
- return anchors.filter(anchor => {
+ return anchors.filter((anchor) => {
const titleMatch = anchor.title.toLowerCase().includes(lowerQuery)
const idMatch = anchor.id.toLowerCase().includes(lowerQuery)
- const tagsMatch = anchor.tags && anchor.tags.some(tag => tag.toLowerCase().includes(lowerQuery))
- const proponentsMatch = anchor.proponents && anchor.proponents.some(p => p.toLowerCase().includes(lowerQuery))
+ const tagsMatch =
+ anchor.tags && anchor.tags.some((tag) => tag.toLowerCase().includes(lowerQuery))
+ const proponentsMatch =
+ anchor.proponents && anchor.proponents.some((p) => p.toLowerCase().includes(lowerQuery))
return titleMatch || idMatch || tagsMatch || proponentsMatch
})
@@ -81,8 +95,9 @@ export async function fetchData() {
dataPromise = Promise.all([
fetchJson('data/anchors.json'),
fetchJson('data/categories.json'),
- fetchJson('data/roles.json')
- ]).then(([anchors, categories, roles]) => ({ anchors, categories, roles }))
+ fetchJson('data/roles.json'),
+ ])
+ .then(([anchors, categories, roles]) => ({ anchors, categories, roles }))
.catch((error) => {
dataPromise = null
throw error
diff --git a/website/src/utils/data-loader.test.js b/website/src/utils/data-loader.test.js
index 019a630..dd19466 100644
--- a/website/src/utils/data-loader.test.js
+++ b/website/src/utils/data-loader.test.js
@@ -6,34 +6,87 @@ import {
getFilteredAnchors,
getCategoryColor,
fetchData,
- __resetDataCacheForTests
+ __resetDataCacheForTests,
} from './data-loader.js'
const mockCategories = [
{
id: 'testing-quality',
name: 'Testing & Quality',
- anchors: ['tdd-london-school', 'tdd-chicago-school', 'mutation-testing']
+ anchors: ['tdd-london-school', 'tdd-chicago-school', 'mutation-testing'],
},
{
id: 'architecture-design',
name: 'Architecture & Design',
- anchors: ['clean-architecture', 'hexagonal-architecture']
- }
+ anchors: ['clean-architecture', 'hexagonal-architecture'],
+ },
]
const mockAnchors = [
- { id: 'tdd-london-school', title: 'TDD, London School', categories: ['testing-quality'], roles: ['software-developer', 'qa-engineer'], tags: ['testing', 'tdd', 'mocking'], proponents: ['Steve Freeman', 'Nat Pryce'] },
- { id: 'tdd-chicago-school', title: 'TDD, Chicago School', categories: ['testing-quality'], roles: ['software-developer', 'qa-engineer'], tags: ['testing', 'tdd'], proponents: ['Kent Beck'] },
- { id: 'mutation-testing', title: 'Mutation Testing', categories: ['testing-quality'], roles: ['software-developer', 'qa-engineer'], tags: ['testing', 'quality'], proponents: [] },
- { id: 'clean-architecture', title: 'Clean Architecture', categories: ['architecture-design'], roles: ['software-architect', 'software-developer'], tags: ['architecture', 'design'], proponents: ['Robert C. Martin'] },
- { id: 'hexagonal-architecture', title: 'Hexagonal Architecture', categories: ['architecture-design'], roles: ['software-architect', 'software-developer'], tags: ['architecture', 'ports-and-adapters'], proponents: ['Alistair Cockburn'] }
+ {
+ id: 'tdd-london-school',
+ title: 'TDD, London School',
+ categories: ['testing-quality'],
+ roles: ['software-developer', 'qa-engineer'],
+ tags: ['testing', 'tdd', 'mocking'],
+ proponents: ['Steve Freeman', 'Nat Pryce'],
+ },
+ {
+ id: 'tdd-chicago-school',
+ title: 'TDD, Chicago School',
+ categories: ['testing-quality'],
+ roles: ['software-developer', 'qa-engineer'],
+ tags: ['testing', 'tdd'],
+ proponents: ['Kent Beck'],
+ },
+ {
+ id: 'mutation-testing',
+ title: 'Mutation Testing',
+ categories: ['testing-quality'],
+ roles: ['software-developer', 'qa-engineer'],
+ tags: ['testing', 'quality'],
+ proponents: [],
+ },
+ {
+ id: 'clean-architecture',
+ title: 'Clean Architecture',
+ categories: ['architecture-design'],
+ roles: ['software-architect', 'software-developer'],
+ tags: ['architecture', 'design'],
+ proponents: ['Robert C. Martin'],
+ },
+ {
+ id: 'hexagonal-architecture',
+ title: 'Hexagonal Architecture',
+ categories: ['architecture-design'],
+ roles: ['software-architect', 'software-developer'],
+ tags: ['architecture', 'ports-and-adapters'],
+ proponents: ['Alistair Cockburn'],
+ },
]
const mockRoles = [
- { id: 'software-developer', name: 'Software Developer / Engineer', anchors: ['tdd-london-school', 'tdd-chicago-school', 'mutation-testing', 'clean-architecture', 'hexagonal-architecture'] },
- { id: 'qa-engineer', name: 'QA Engineer / Tester', anchors: ['tdd-london-school', 'tdd-chicago-school', 'mutation-testing'] },
- { id: 'software-architect', name: 'Software Architect', anchors: ['clean-architecture', 'hexagonal-architecture'] }
+ {
+ id: 'software-developer',
+ name: 'Software Developer / Engineer',
+ anchors: [
+ 'tdd-london-school',
+ 'tdd-chicago-school',
+ 'mutation-testing',
+ 'clean-architecture',
+ 'hexagonal-architecture',
+ ],
+ },
+ {
+ id: 'qa-engineer',
+ name: 'QA Engineer / Tester',
+ anchors: ['tdd-london-school', 'tdd-chicago-school', 'mutation-testing'],
+ },
+ {
+ id: 'software-architect',
+ name: 'Software Architect',
+ anchors: ['clean-architecture', 'hexagonal-architecture'],
+ },
]
describe('buildTreemapData', () => {
@@ -59,7 +112,7 @@ describe('buildTreemapData', () => {
it('should include anchor metadata in leaf nodes', () => {
const result = buildTreemapData(mockCategories, mockAnchors)
- const tddLondon = result[0].children.find(c => c.id === 'tdd-london-school')
+ const tddLondon = result[0].children.find((c) => c.id === 'tdd-london-school')
expect(tddLondon).toBeDefined()
expect(tddLondon.name).toBe('TDD, London School')
expect(tddLondon.roles).toEqual(['software-developer', 'qa-engineer'])
@@ -86,7 +139,7 @@ describe('getAnchorsByRole', () => {
const result = getAnchorsByRole(mockAnchors, 'qa-engineer')
expect(result).toHaveLength(3)
- expect(result.every(a => a.roles.includes('qa-engineer'))).toBe(true)
+ expect(result.every((a) => a.roles.includes('qa-engineer'))).toBe(true)
})
it('should return all anchors when no role specified', () => {
@@ -183,7 +236,7 @@ describe('getFilteredAnchors', () => {
const result = getFilteredAnchors(mockAnchors, 'qa-engineer', '')
expect(result).toHaveLength(3)
- expect(result.every(a => a.roles.includes('qa-engineer'))).toBe(true)
+ expect(result.every((a) => a.roles.includes('qa-engineer'))).toBe(true)
})
it('should apply only search filter when no role', () => {
diff --git a/website/src/utils/search-index.js b/website/src/utils/search-index.js
index 588d912..2f4318f 100644
--- a/website/src/utils/search-index.js
+++ b/website/src/utils/search-index.js
@@ -16,7 +16,7 @@ export async function buildSearchIndex(anchors) {
if (indexReady) return
if (buildingPromise) return buildingPromise
- console.log('Building search index for', anchors.length, 'anchors...')
+ console.warn('Building search index for', anchors.length, 'anchors...')
buildingPromise = (async () => {
for (let i = 0; i < anchors.length; i += BATCH_SIZE) {
@@ -38,7 +38,7 @@ export async function buildSearchIndex(anchors) {
tags: anchor.tags || [],
proponents: anchor.proponents || [],
roles: anchor.roles || [],
- categories: anchor.categories || []
+ categories: anchor.categories || [],
})
} catch (error) {
console.warn(`Error indexing ${anchor.id}:`, error)
@@ -49,7 +49,7 @@ export async function buildSearchIndex(anchors) {
}
indexReady = true
- console.log('Search index built:', searchIndex.size, 'anchors indexed')
+ console.warn('Search index built:', searchIndex.size, 'anchors indexed')
})()
try {
@@ -73,10 +73,10 @@ function extractSearchableText(adocContent) {
text = text.replace(/^=+\s+/gm, '')
// Remove block delimiters
- text = text.replace(/^[*_\-=]{4,}$/gm, '')
+ text = text.replace(/^[*_=-]{4,}$/gm, '')
// Remove link syntax but keep text
- text = text.replace(/link:([^\[]+)\[([^\]]+)\]/g, '$2')
+ text = text.replace(/link:([^[]+)\[([^\]]+)\]/g, '$2')
text = text.replace(/<<([^,]+),([^>]+)>>/g, '$2')
text = text.replace(/<<([^>]+)>>/g, '$1')
@@ -87,7 +87,7 @@ function extractSearchableText(adocContent) {
text = text.replace(/`([^`]+)`/g, '$1') // code
// Remove list markers
- text = text.replace(/^[\*\-]\s+/gm, '')
+ text = text.replace(/^[*-]\s+/gm, '')
text = text.replace(/^\d+\.\s+/gm, '')
// Remove source blocks
@@ -122,19 +122,19 @@ export function search(query) {
let score = 0
// Check each search word
- words.forEach(word => {
+ words.forEach((word) => {
// Title match (highest weight)
if (data.title.toLowerCase().includes(word)) {
score += 10
}
// Proponents match (high weight)
- if (data.proponents.some(p => p.toLowerCase().includes(word))) {
+ if (data.proponents.some((p) => p.toLowerCase().includes(word))) {
score += 5
}
// Tags match (medium weight)
- if (data.tags.some(t => t.toLowerCase().includes(word))) {
+ if (data.tags.some((t) => t.toLowerCase().includes(word))) {
score += 3
}
@@ -145,12 +145,16 @@ export function search(query) {
})
// Only include if all words matched
- if (score > 0 && words.every(word =>
- data.title.toLowerCase().includes(word) ||
- data.proponents.some(p => p.toLowerCase().includes(word)) ||
- data.tags.some(t => t.toLowerCase().includes(word)) ||
- data.content.includes(word)
- )) {
+ if (
+ score > 0 &&
+ words.every(
+ (word) =>
+ data.title.toLowerCase().includes(word) ||
+ data.proponents.some((p) => p.toLowerCase().includes(word)) ||
+ data.tags.some((t) => t.toLowerCase().includes(word)) ||
+ data.content.includes(word)
+ )
+ ) {
matches.push({ anchorId, score })
}
})
@@ -158,7 +162,7 @@ export function search(query) {
// Sort by score (highest first)
matches.sort((a, b) => b.score - a.score)
- return matches.map(m => m.anchorId)
+ return matches.map((m) => m.anchorId)
}
/**
diff --git a/website/src/utils/search-index.test.js b/website/src/utils/search-index.test.js
index 15a9fa1..d69f5a7 100644
--- a/website/src/utils/search-index.test.js
+++ b/website/src/utils/search-index.test.js
@@ -4,7 +4,7 @@ import {
search,
isIndexReady,
isIndexBuilding,
- __resetSearchIndexForTests
+ __resetSearchIndexForTests,
} from './search-index.js'
describe('search-index', () => {
@@ -12,7 +12,7 @@ describe('search-index', () => {
__resetSearchIndexForTests()
global.fetch = vi.fn().mockResolvedValue({
ok: true,
- text: async () => '= Test Anchor\n\nA practical testing method for teams.'
+ text: async () => '= Test Anchor\n\nA practical testing method for teams.',
})
})
@@ -22,8 +22,18 @@ describe('search-index', () => {
it('builds index and enables full-text search', async () => {
const anchors = [
- { id: 'tdd-london-school', title: 'TDD London', tags: ['testing'], proponents: ['Steve Freeman'] },
- { id: 'clean-architecture', title: 'Clean Architecture', tags: ['architecture'], proponents: ['Robert Martin'] }
+ {
+ id: 'tdd-london-school',
+ title: 'TDD London',
+ tags: ['testing'],
+ proponents: ['Steve Freeman'],
+ },
+ {
+ id: 'clean-architecture',
+ title: 'Clean Architecture',
+ tags: ['architecture'],
+ proponents: ['Robert Martin'],
+ },
]
await buildSearchIndex(anchors)