UNPKG

solcco

Version:

Documentation generator for Solidity with a literary bent.

827 lines (720 loc) 17.8 kB
<!doctype html> <html> <head> <style> /* PrismJS 1.22.0 https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+solidity&plugins=line-numbers+autolinker+match-braces */ /** * prism.js default theme for JavaScript, CSS and HTML * Based on dabblet (http://dabblet.com) * @author Lea Verou */ code[class*="language-"], pre[class*="language-"] { color: black; background: none; text-shadow: 0 1px white; font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; font-size: 1em; text-align: left; white-space: pre; word-spacing: normal; word-break: normal; word-wrap: normal; line-height: 1.5; -moz-tab-size: 4; -o-tab-size: 4; tab-size: 4; -webkit-hyphens: none; -moz-hyphens: none; -ms-hyphens: none; hyphens: none; } pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { text-shadow: none; background: #b3d4fc; } pre[class*="language-"]::selection, pre[class*="language-"] ::selection, code[class*="language-"]::selection, code[class*="language-"] ::selection { text-shadow: none; background: #b3d4fc; } @media print { code[class*="language-"], pre[class*="language-"] { text-shadow: none; } } /* Code blocks */ pre[class*="language-"] { padding: 1em; margin: 0.5em 0; overflow: auto; } :not(pre) > code[class*="language-"], pre[class*="language-"] { background: #f5f2f0; } /* Inline code */ :not(pre) > code[class*="language-"] { padding: 0.1em; border-radius: 0.3em; white-space: normal; } .token.comment, .token.prolog, .token.doctype, .token.cdata { color: slategray; } .token.punctuation { color: #999; } .token.namespace { opacity: 0.7; } .token.property, .token.tag, .token.boolean, .token.number, .token.constant, .token.symbol, .token.deleted { color: #905; } .token.selector, .token.attr-name, .token.string, .token.char, .token.builtin, .token.inserted { color: #690; } .token.operator, .token.entity, .token.url, .language-css .token.string, .style .token.string { color: #9a6e3a; /* This background color was intended by the author of this theme. */ background: hsla(0, 0%, 100%, 0.5); } .token.atrule, .token.attr-value, .token.keyword { color: #07a; } .token.function, .token.class-name { color: #dd4a68; } .token.regex, .token.important, .token.variable { color: #e90; } .token.important, .token.bold { font-weight: bold; } .token.italic { font-style: italic; } .token.entity { cursor: help; } pre[class*="language-"].line-numbers { position: relative; padding-left: 3.8em; counter-reset: linenumber; } pre[class*="language-"].line-numbers > code { position: relative; white-space: inherit; } .line-numbers .line-numbers-rows { position: absolute; pointer-events: none; top: 0; font-size: 100%; left: -3.8em; width: 3em; /* works for line-numbers below 1000 lines */ letter-spacing: -1px; border-right: 1px solid #999; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } .line-numbers-rows > span { display: block; counter-increment: linenumber; } .line-numbers-rows > span:before { content: counter(linenumber); color: #999; display: block; padding-right: 0.8em; text-align: right; } .token a { color: inherit; } .token.punctuation.brace-hover, .token.punctuation.brace-selected { outline: solid 1px; } .rainbow-braces .token.punctuation.brace-level-1, .rainbow-braces .token.punctuation.brace-level-5, .rainbow-braces .token.punctuation.brace-level-9 { color: #e50; opacity: 1; } .rainbow-braces .token.punctuation.brace-level-2, .rainbow-braces .token.punctuation.brace-level-6, .rainbow-braces .token.punctuation.brace-level-10 { color: #0b3; opacity: 1; } .rainbow-braces .token.punctuation.brace-level-3, .rainbow-braces .token.punctuation.brace-level-7, .rainbow-braces .token.punctuation.brace-level-11 { color: #26f; opacity: 1; } .rainbow-braces .token.punctuation.brace-level-4, .rainbow-braces .token.punctuation.brace-level-8, .rainbow-braces .token.punctuation.brace-level-12 { color: #e0e; opacity: 1; } </style> <link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&display=swap" rel="stylesheet"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/katex.min.css"> <style> html { scroll-behavior: smooth; } body { margin: 0; display: flex; flex-direction: column; align-items: stretch; } h1 { font-size: 1.5em; } h2 { font-size: 1.32em; } h3 { font-size: 1.17em; } .level { display: flex; flex-direction: row; line-height: 1.4; align-items: baseline; position: relative; } .level:first-child { padding-top: 3rem; } .level.scrollHighlighted { background: rgb(150 159 228 / 48%); border-right: 10px solid #515ba27a; } .titleLevel .left-background { padding-top: 2em; //border-bottom: 4px solid #e5e5ee; } .left, .right { //border: 1px solid red; } .left-background { background: #f5f5ff; border-right: 1px solid #e5e5ee; width: 34rem; position: absolute; top: 0px; bottom: 0px; left: -1px; z-index: -1; padding-left: 4em; } .hover-background { border-top: 1px solid rgb(229 229 238 / 0.8); border-bottom: 1px solid rgb(229 229 238 / 0.3); right: 0px; width: auto; background: rgb(254 255 227 / 0.1); position: absolute; top: 0px; bottom: 0px; left: -1px; z-index: -1; padding-left: 4em; visibility: hidden; } body:not(.bodyFocusing) .level:hover .hover-background { visibility: visible; } .left { padding-left: 4rem; width: 34rem; align-items: stretch; font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; text-align:right; flex-shrink: 0; flex-grow: 0; } .level .left { font-size: 1.1em; line-height: 1.44; } .lineComment { max-width: 80%; font-size:0.9em; text-align: right; background: white; display: inline-flex; flex-direction: column; //margin-right: calc(-1px); padding-top: 0.2rem; padding-bottom: 0.2rem; border: 1px solid #e5e5ee; border-right: none; padding-right: 1rem; padding-left: 1rem; margin-bottom: 2px; margin-left: 1rem; border-radius: 5px 0px 0px 5px; } .lineComment p { margin: 0 } .blockComment { margin-right: 3rem; text-align: justify; } .blockComment *:not(li,code,.katex *) { margin-top: 0px; margin-bottom: 1.44em; } .blockComment *:last-child:not(li,code,.katex *) { margin-bottom: 0.72em; } .blockComment *:first-child:not(li,code,.katex *) { margin-top: 0.72em; } .blockComment p + ul, .blockComment p + ol { margin-top: -0.72em; } .blockComment ul, .blockComment ol { margin-bottom: 0.72em; } // fixme not working like I want .blockCommont:not(:first-child) { margin-top: 1em; } .blockComment pre { white-space: pre-wrap; font-size: 0.84em; line-height: 1.44; margin-top: -1.055em; margin-bottom: 1.055em; background: hsl(240 21% 102% / 1); padding-top: 0.5em; padding-bottom: 0.5em; padding-left: 0.5em; padding-right: 2em; } p code, ul code, ol code { background: hsl(240 21% 102% / 1); padding: 0.2em; } .right { position: relative; top: 0px; width: 50%; //padding-left: 0.5rem; display: flex; } .right, .lines { line-height: 1.95; } .focusing { background: rgb(254 255 227); } .right:hover { //border: 1px solid blue; } .right code { } .codewrap { display: flex; flex-direction: row; transition: transform 300ms ease-in-out; } .focuser { align-self: stretch; flex-shrink: 0; font-size: 1.3rem; text-align: center; display: flex; flex-direction: row; justify-content: flex-start; color: white; z-index: 1000; position: absolute; left: 0; top: 0; width: 3.2rem; height: 100%; } .focus-icon { //line-height: 0.85; font-size: 1.5rem; width: 1em; flex-grow: 0; flex-shrink: 0; } .focus-icon:before, .focus-icon:after { position: absolute; text-align: center; display: block; left: 0; width: 1em; visibility: hidden; color: #797979; } .focus-icon:before { content:"↡"; top: -1.55em; pointer-events: none; } .focus-icon:after { content:"↟"; bottom: -1.45em; pointer-events: none; } body:not(.bodyFocusing) .focuser:hover, body:not(.bodyFocusing) .focusing .focuser { border-top: 1px dashed #797979; border-bottom: 1px dashed #797979; cursor: pointer; } body:not(.bodyFocusing) .focuser:hover .focus-icon:before, body:not(.bodyFocusing) .focuser:hover .focus-icon:after, body:not(.bodyFocusing) .focusing .focus-icon:before, body:not(.bodyFocusing) .focusing .focus-icon:after { visibility: visible; } pre { margin: 0; } .right { position: relative; } .lines { width: content; flex-shrink: 0; margin-right: 0; color: #797979; text-align: right; display: flex; justify-content: flex-end; margin-right: 1em; } .lines pre { width: 3.5em; pointer-events: none; } body { display: flex; flex-direction: row; } nav { width: 22em; flex-shrink: 0; background: hsl(240 47% 17% / 1); position: sticky; top: 0px; font-size: 0.9em; padding-top: 3rem; padding-bottom: 3rem; height: calc(100vh - 6rem); font-family: 'Lato', sans-serif; background: #f5f5ff; overflow-y: auto; } nav a { color: hsl(240 82% 98% / 1); color: black; display: block; text-decoration: none; line-height: 1; padding-left: 3rem; } nav a:hover { background: white; } nav a.highlight { background: white; } nav a.toc-file:hover { background: black; } .toc-file { font-family: monospace; font-size: 1.3em; padding-top: 0.7em; padding-bottom: 0.6em; border-top: 1px solid #e5e5ee; border-bottom: 1px solid #e5e5ee; background: #37718E; color: white; } * + .toc-file { margin-top: 2em; } .toc-h1 { font-size: 1.2em; font-weight: 600; padding-top: 0.6em; padding-bottom: 0.55em; } .toc-h2 { font-size: 1em; padding-left: 3.5rem; padding-top: 0.4em; padding-bottom: 0.4em; } .toc-h3 + .toc-h2 { margin-top: .4em; } .toc-h3 + .toc-h1, .toc-h2 + .toc-h1 { margin-top: .4em; } .toc-h3 { font-size: 0.8em; padding-left: 6.5rem; padding-top: 0.4em; padding-botom: 0.6em; } a { color: black; } .filebreak { width: calc(100% - 4em - 2px); font-family: monospace; /*background: #e5e5ee;*/ background: #37718E; color: white; text-align: left; font-size: 1.18em !important; padding-top: 0.7em; padding-bottom: 0.6em; line-height: 1 !important; border-top: 1px solid #e5e5ee; border-bottom: 1px solid #e5e5ee; } .katex { font-size: 1em; } </style> <script> /* Bounds of DOM element, including margin */ let bounds = (el,wsy) => { const rect = el.getBoundingClientRect(); const style = getComputedStyle(el); return { top: wsy + rect.top - parseInt(style.marginTop), bottom: wsy + rect.bottom + parseInt(style.marginBottom) }; }; window.addEventListener('DOMContentLoaded', () => { /* For future reference. The current TOC highlight fails when you scroll up into a no-headings zone. Then the highlighted heading is the one below the bottom of the viewport; it should be the one above the top of the viewport. A more complete decision tree for future implementation: * have an array of all heading elements, and they know their position in the array * have a pointer to "lowest heading above viewport lower edge ("the fold"). * keep set of visible elements * when an element comes in or out of the set, run: lowestAboveFold = i point = lower above fold for entry in entries if entry.out if entry.too_low if point below or is entry point = entry.prev else () else (entry.too_high) if nobody_visible () [???] else () [???] else (entry.in) if point above or is entry point = entry */ /* Keep roughly track of currently viewed section, highlight corresponding toc in nav */ const visibleHeadings = new Set(); const observer = new IntersectionObserver(entries => { for (const entry of entries) visibleHeadings[entry.isIntersecting ? 'add' : 'delete'](entry.target); }, {threshold:0}); const headingsSelector = Array.from({length: {{level}} }, (_,i) => `h${i+1}`).join(', '); const headings = document.querySelectorAll(headingsSelector); for (const heading of headings) observer.observe(heading); let curHeading = null; window.addEventListener('scroll', e => { let minBelow = [Infinity,null]; for (const heading of visibleHeadings) { const b = heading.getBoundingClientRect().bottom; if (b < minBelow[0]) minBelow = [b,heading]; } if (minBelow[1] !== curHeading) { if (minBelow[1] && curHeading) { document.querySelector(`a[href="#${curHeading.id}"]`).classList.remove('highlight'); } if (minBelow[1]) { curHeading = minBelow[1]; document.querySelector(`a[href="#${curHeading.id}"]`).classList.add('highlight'); } } }); /* Initialize cache _translate to 0 */ for (const focuser of document.querySelectorAll('.codewrap')) { focuser._translate = 0; } /* Loop through all codewraps. Treat codewraps before t (which is a codewrap) * in reverse order. Stack codewraps above and below t. */ const focus = (t) => { const wsy = window.scrollY; // cache value for performance, big difference in chrome let isBefore = true; const tBounds = bounds(t,wsy); let prevBottom = tBounds.bottom - t._translate; let prevTop = tBounds.top - t._translate; t._translate = 0; let befores = []; // apply changes after t from t downwards for (const cur of document.querySelectorAll(".codewrap")) { if (cur === t) { isBefore = false; } else if (isBefore) { befores.push(cur); } else { const cBounds = bounds(cur,wsy); const _translate = prevBottom - cBounds.top; cur._translate = cur._translate + _translate; prevBottom = prevBottom + (cBounds.bottom - cBounds.top); } } // apply changes before t from t upwards let cur; while ((cur = befores.pop())) { const cBounds = bounds(cur,wsy); const _translate = prevTop - cBounds.bottom; cur._translate = cur._translate + _translate; prevTop = prevTop - (cBounds.bottom - cBounds.top); } // batch changes after reading layout to avoid layout thrashing for (const cur of document.querySelectorAll('.codewrap')) { cur.style.transform = `translate(0px,${cur._translate}px)`; } }; /* Stop focusing */ let currentFocuser; const defocus = () => { currentFocuser.parentNode.classList.remove("focusing"); document.body.classList.remove('bodyFocusing'); currentFocuser = undefined; for (const t of document.querySelectorAll(".codewrap")) { t.style.transform = "translate(0px,0px)"; t._translate = 0; } }; /* Defocus when clicking anywhere and currently in focus */ document.body.addEventListener('click', e => { if (currentFocuser) defocus(); }); /* Focus when clicking a focuser. Disabled when in focus. */ for (const focuser of document.querySelectorAll('.focuser')) { focuser.addEventListener('click', e => { if (currentFocuser) return; currentFocuser = e.currentTarget; focus(currentFocuser.parentNode.querySelector('.codewrap')); currentFocuser.parentNode.classList.add("focusing"); document.body.classList.add('bodyFocusing'); e.stopPropagation(); }); } /* Avoid horizontal scrolling when clicking on internal anchors */ let scrollHighlighted = null; const doScroll = target => target.scrollIntoView({behavior: "auto", block: "start", inline: "end"}); for (const anchor of document.querySelectorAll("a[href^='#']")) { anchor.addEventListener('click', e => { e.preventDefault(); history.pushState(null, null, anchor.getAttribute('href')); // Must use [id=] syntax instead of # syntax to escape forward slash in anchor name. const target = document.querySelector(`[id='${anchor.getAttribute("href").slice(1)}']`); if (scrollHighlighted) { scrollHighlighted.classList.remove('scrollHighlighted'); } scrollHighlighted = target.closest('.level'); if (scrollHighlighted) { doScroll(scrollHighlighted); scrollHighlighted.classList.add('scrollHighlighted'); } else { doScroll(target); } }); }; }); </script> </head> <body> <nav> {{#each toc}} <a href="#{{slug}}" class="toc-{{tag}}">{{title}}</a> {{/each}} </nav> <main> {{#each packedFiles}} <div class="level titleLevel"> <div class="left-background"></div> <div id="{{fileSlug}}" class="left filebreak">{{file}}</div> </div> {{#each packedResults}} <div class="level"> <div class="left-background"></div> <div class="hover-background"></div> <div class="left"> {{#if lineComment}} <div class="lineComment">{{{lineComment}}}</div> {{/if}} {{#if blockComment}} <div class="blockComment">{{{blockComment}}}</div> {{/if}} </div> <code class="right solidity"> <div class="codewrap"> <code class="lines"><pre>{{{lines}}}</pre></code> <pre>{{{code}}}</pre> </div> <div class="focuser"> <div class="focus-icon"><!--⥮--></div> <div class="warning-overlay"></div> </div> </code> </div> {{/each}} {{/each}} </main> </body> </html>