Initial commit. monorepo deps are copied in a dirty way to the vendor folder
This commit is contained in:
commit
06593ac488
53 files changed
+7692
No files matched your search
Binary file not shown.
|
After Width: | Height: | Size: 59 KiB |
@@ -0,0 +1,93 @@
|
||||
Copyright 2020 The Space Grotesk Project Authors (https://github.com/floriankarsten/space-grotesk)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,422 @@
|
||||
/* The print stylesheet of the SAST/SCA report.
|
||||
*
|
||||
* Follows the design sample in `sample_report_template/`. Everything is expressed here rather than
|
||||
* in the template: the template places content, this decides what it looks like, and the two are
|
||||
* changed for different reasons.
|
||||
*
|
||||
* Space Grotesk throughout, with a monospace face for anything a reader might have to type or
|
||||
* compare character by character -- identifiers, paths, package URLs, CVSS vectors, VEX
|
||||
* justifications. That distinction is the one typographic rule the whole report rests on.
|
||||
*/
|
||||
|
||||
@font-face {
|
||||
font-family: "Space Grotesk";
|
||||
font-weight: 400;
|
||||
src: url("fonts/SpaceGrotesk-Regular.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Space Grotesk";
|
||||
font-weight: 500;
|
||||
src: url("fonts/SpaceGrotesk-Medium.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Space Grotesk";
|
||||
font-weight: 700;
|
||||
src: url("fonts/SpaceGrotesk-Bold.ttf");
|
||||
}
|
||||
|
||||
/* Shipped rather than asked of the host. `monospace` resolves to whatever a machine happens to
|
||||
have -- DejaVu on one, Andale on another -- and a report whose identifiers change shape between
|
||||
two machines is a report nobody can compare. Space Mono is the companion face to Space Grotesk. */
|
||||
@font-face {
|
||||
font-family: "Space Mono";
|
||||
font-weight: 400;
|
||||
src: url("fonts/SpaceMono-Regular.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Space Mono";
|
||||
font-weight: 700;
|
||||
src: url("fonts/SpaceMono-Bold.ttf");
|
||||
}
|
||||
|
||||
:root {
|
||||
--ink: #1a1a1a;
|
||||
--muted: #55585c;
|
||||
--rule: #1a1a1a;
|
||||
--border: #c9cbcd;
|
||||
--header-fill: #e7e8ea;
|
||||
--label-fill: #f4f5f6;
|
||||
/* The filtering reason is the one row that argues rather than states, and it is tinted so that
|
||||
it reads as an aside even when the page is skimmed. */
|
||||
--aside-fill: #fdf5ea;
|
||||
--critical: #d0021b;
|
||||
--high: #e8710a;
|
||||
--medium: #f0ad20;
|
||||
--low: #1f9d55;
|
||||
}
|
||||
|
||||
@page {
|
||||
size: A4;
|
||||
margin: 22mm 18mm 18mm 18mm;
|
||||
|
||||
@bottom-left {
|
||||
content: string(scan-footer);
|
||||
font-family: "Space Grotesk", sans-serif;
|
||||
font-size: 6.5pt;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
@bottom-center {
|
||||
content: counter(page);
|
||||
font-family: "Space Grotesk", sans-serif;
|
||||
font-size: 6.5pt;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
@bottom-right {
|
||||
content: string(date-footer);
|
||||
font-family: "Space Grotesk", sans-serif;
|
||||
font-size: 6.5pt;
|
||||
color: var(--muted);
|
||||
}
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: "Space Grotesk", sans-serif;
|
||||
font-size: 8.5pt;
|
||||
line-height: 1.45;
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
code,
|
||||
.mono {
|
||||
font-family: "Space Mono", monospace;
|
||||
font-size: 0.93em;
|
||||
}
|
||||
|
||||
/* Carried into the running footer on every page. Set once, on the cover. */
|
||||
.footer-scan {
|
||||
string-set: scan-footer content();
|
||||
}
|
||||
|
||||
.footer-date {
|
||||
string-set: date-footer content();
|
||||
}
|
||||
|
||||
.footer-scan,
|
||||
.footer-date {
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
/* --- Cover ------------------------------------------------------------------------------- */
|
||||
|
||||
.cover-mark {
|
||||
text-align: right;
|
||||
margin-bottom: 42mm;
|
||||
}
|
||||
|
||||
.cover-mark img {
|
||||
height: 15mm;
|
||||
}
|
||||
|
||||
.cover-title {
|
||||
font-size: 19pt;
|
||||
font-weight: 400;
|
||||
margin: 0 0 9mm 0;
|
||||
}
|
||||
|
||||
/* --- Headings ---------------------------------------------------------------------------- */
|
||||
|
||||
/* A section heading and the rule under it are one thing, so the rule belongs to the heading and
|
||||
cannot be separated from it by a page break. */
|
||||
h1 {
|
||||
font-size: 12.5pt;
|
||||
font-weight: 700;
|
||||
margin: 12mm 0 4mm 0;
|
||||
padding-bottom: 1.6mm;
|
||||
border-bottom: 0.8pt solid var(--rule);
|
||||
break-after: avoid;
|
||||
}
|
||||
|
||||
h1:first-of-type {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 9pt;
|
||||
font-weight: 700;
|
||||
margin: 7mm 0 2.5mm 0;
|
||||
break-after: avoid;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 8.5pt;
|
||||
font-weight: 700;
|
||||
margin: 5mm 0 2mm 0;
|
||||
break-after: avoid;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 0 2.5mm 0;
|
||||
}
|
||||
|
||||
p.note {
|
||||
color: var(--ink);
|
||||
max-width: 155mm;
|
||||
}
|
||||
|
||||
/* --- Definition rows --------------------------------------------------------------------- */
|
||||
|
||||
/* Label left, value right, on one grid so that every block of them lines up down the page even
|
||||
when they are separated by headings. */
|
||||
.facts {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 3mm;
|
||||
}
|
||||
|
||||
.facts td {
|
||||
padding: 0.7mm 0;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.facts td:first-child {
|
||||
width: 46mm;
|
||||
padding-right: 4mm;
|
||||
}
|
||||
|
||||
.facts.wide td:first-child {
|
||||
width: 62mm;
|
||||
}
|
||||
|
||||
.facts tr.gap td {
|
||||
padding-top: 4mm;
|
||||
}
|
||||
|
||||
/* --- Ledger tables (severity counts, languages) ------------------------------------------- */
|
||||
|
||||
/* Ruled above and below with hairlines between, and a heavier line before the total: the shape a
|
||||
reader already knows from an invoice, used for the same reason -- the last row is a sum. */
|
||||
.ledger {
|
||||
width: 62%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 4mm;
|
||||
}
|
||||
|
||||
.ledger th,
|
||||
.ledger td {
|
||||
padding: 1.4mm 1mm;
|
||||
border-bottom: 0.4pt solid var(--border);
|
||||
}
|
||||
|
||||
.ledger thead th {
|
||||
border-bottom: 0.8pt solid var(--rule);
|
||||
text-align: left;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.ledger td:last-child {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.ledger tr.total td {
|
||||
border-top: 0.8pt solid var(--rule);
|
||||
border-bottom: none;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* --- Grid tables -------------------------------------------------------------------------- */
|
||||
|
||||
.grid {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 4mm;
|
||||
/* A table that splits across a page keeps its header on the second half. */
|
||||
break-inside: auto;
|
||||
}
|
||||
|
||||
.grid th,
|
||||
.grid td {
|
||||
border: 0.4pt solid var(--border);
|
||||
padding: 1.6mm 2mm;
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.grid thead th {
|
||||
background: var(--header-fill);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.grid tr.total td {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.grid tr,
|
||||
.facts tr {
|
||||
break-inside: avoid;
|
||||
}
|
||||
|
||||
/* --- Cards -------------------------------------------------------------------------------- */
|
||||
|
||||
/* One finding, as a titled block of label/value rows. Kept on one page where it fits: a card split
|
||||
down the middle loses the thing that makes it a card. */
|
||||
.card {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 3.5mm;
|
||||
break-inside: avoid;
|
||||
}
|
||||
|
||||
.card caption {
|
||||
background: var(--header-fill);
|
||||
border: 0.4pt solid var(--border);
|
||||
padding: 1.6mm 2mm;
|
||||
text-align: left;
|
||||
font-weight: 700;
|
||||
caption-side: top;
|
||||
}
|
||||
|
||||
.card th,
|
||||
.card td {
|
||||
border: 0.4pt solid var(--border);
|
||||
padding: 1.6mm 2mm;
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.card th {
|
||||
width: 34mm;
|
||||
background: var(--label-fill);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.card tr.aside th,
|
||||
.card tr.aside td {
|
||||
background: var(--aside-fill);
|
||||
}
|
||||
|
||||
/* The justification itself, set as the token it is rather than as prose about a token. */
|
||||
.token {
|
||||
font-family: "Space Mono", monospace;
|
||||
font-size: 0.93em;
|
||||
background: #ffffff;
|
||||
border: 0.4pt solid var(--border);
|
||||
border-radius: 1mm;
|
||||
padding: 0.3mm 1.2mm;
|
||||
}
|
||||
|
||||
/* --- Severity ----------------------------------------------------------------------------- */
|
||||
|
||||
.sev {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.sev-critical {
|
||||
color: var(--critical);
|
||||
}
|
||||
|
||||
.sev-high {
|
||||
color: var(--high);
|
||||
}
|
||||
|
||||
.sev-medium {
|
||||
color: var(--medium);
|
||||
}
|
||||
|
||||
.sev-low {
|
||||
color: var(--low);
|
||||
}
|
||||
|
||||
/* --- Distribution bars --------------------------------------------------------------------- */
|
||||
|
||||
/* Label, count, then one bar made of stacked severity segments. The bar is scaled against the
|
||||
largest row rather than against the total, so the shape of the distribution is what is read and
|
||||
the busiest row fills the width. */
|
||||
.bars {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 1.5mm;
|
||||
}
|
||||
|
||||
.bars td {
|
||||
border: 0.4pt solid var(--border);
|
||||
padding: 1.2mm 2mm;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.bars td.count {
|
||||
width: 12mm;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.bars td.track {
|
||||
width: 50%;
|
||||
padding: 1.2mm 2mm;
|
||||
}
|
||||
|
||||
.bar {
|
||||
height: 3mm;
|
||||
width: 100%;
|
||||
/* The segments are inline-block, so the newlines between them in the template would be
|
||||
rendered as spaces and push a full-width bar onto a second line. */
|
||||
font-size: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.bar span {
|
||||
display: inline-block;
|
||||
height: 3mm;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.seg-critical {
|
||||
background: var(--critical);
|
||||
}
|
||||
|
||||
.seg-high {
|
||||
background: var(--high);
|
||||
}
|
||||
|
||||
.seg-medium {
|
||||
background: var(--medium);
|
||||
}
|
||||
|
||||
.seg-low {
|
||||
background: var(--low);
|
||||
}
|
||||
|
||||
/* A distribution and its legend travel together. Where the pair does not fit, it moves to the
|
||||
next page whole rather than leaving a stranded row and an orphaned key behind. */
|
||||
.block {
|
||||
break-inside: avoid;
|
||||
}
|
||||
|
||||
.legend {
|
||||
font-size: 7.5pt;
|
||||
color: var(--ink);
|
||||
margin-bottom: 5mm;
|
||||
}
|
||||
|
||||
.legend .key {
|
||||
display: inline-block;
|
||||
width: 2.4mm;
|
||||
height: 2.4mm;
|
||||
margin-right: 1.2mm;
|
||||
}
|
||||
|
||||
.legend .item {
|
||||
margin-right: 4mm;
|
||||
}
|
||||
|
||||
.legend .caveat {
|
||||
color: var(--muted);
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
{#
|
||||
The SAST/SCA report, after the design sample in `sample_report_template/`.
|
||||
|
||||
This file places content and nothing else: every dimension, colour and rule lives in `report.css`.
|
||||
Each section is guarded by the data it needs, so a report of a scan that ran half the pipeline is
|
||||
the same document with fewer sections rather than a document full of empty tables.
|
||||
|
||||
The context this expects is described by `layout.CONTEXT`, and `sample.sample_context()` builds a
|
||||
complete one.
|
||||
#}
|
||||
{# A value is drawn by what it is, not by where it sits: an identifier, a path or a CVSS vector is
|
||||
set in the monospace face wherever it appears, and a severity carries its colour. #}
|
||||
{% macro value(row) %}
|
||||
{% if row.token %}<span class="token">{{ row.token }}</span> — {% endif %}
|
||||
{% if row.kind == "severity" %}
|
||||
<span class="sev sev-{{ row.value|lower }}">{{ row.value }}</span>
|
||||
{% elif row.kind == "mono" %}
|
||||
<span class="mono">{{ row.value }}</span>
|
||||
{% else %}
|
||||
{{ row.value }}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro facts(rows, wide=false) %}
|
||||
<table class="facts{% if wide %} wide{% endif %}">
|
||||
{% for row in rows %}
|
||||
<tr{% if row.gap %} class="gap"{% endif %}>
|
||||
<td>{{ row.label }}:</td>
|
||||
<td>{{ value(row) }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro card(title, rows) %}
|
||||
{# Wrapped, because break-inside on the table does not hold its caption: the title would stay on
|
||||
one page while the rows it titles moved to the next. #}
|
||||
<div class="block">
|
||||
<table class="card">
|
||||
<caption>{{ title }}</caption>
|
||||
{% for row in rows %}
|
||||
<tr{% if row.aside %} class="aside"{% endif %}>
|
||||
<th>{{ row.label }}</th>
|
||||
<td>{{ value(row) }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{# Scaled against the busiest row, not against the total: what is read off a row of these is which
|
||||
one is the outlier, and a scale set by the sum flattens all of them. #}
|
||||
{% macro distribution(rows, legend) %}
|
||||
{# The bars and the legend that decodes them are one thing; a break between them leaves a reader
|
||||
with coloured segments and no key. #}
|
||||
<div class="block">
|
||||
<table class="bars">
|
||||
{% for row in rows %}
|
||||
<tr>
|
||||
<td{% if row.mono %} class="mono"{% endif %}>{{ row.label }}</td>
|
||||
<td class="count">{{ row.count }}</td>
|
||||
<td class="track">
|
||||
<div class="bar">
|
||||
{% for part in row.parts %}
|
||||
<span class="seg-{{ part.severity|lower }}" style="width: {{ part.share }}%"></span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
<div class="legend">
|
||||
{% for item in legend.entries %}
|
||||
<span class="item"><span class="key seg-{{ item.severity|lower }}"></span>{{ item.label }}</span>
|
||||
{% endfor %}
|
||||
{% if legend.caveat %}<span class="caveat">— {{ legend.caveat }}</span>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro grid(table) %}
|
||||
<table class="grid">
|
||||
<thead>
|
||||
<tr>{% for column in table.columns %}<th>{{ column }}</th>{% endfor %}</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for row in table.rows %}
|
||||
<tr{% if row.total %} class="total"{% endif %}>
|
||||
{% for cell in row.cells %}
|
||||
<td>{% if cell is mapping %}{{ value(cell) }}{% else %}{{ cell }}{% endif %}</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endmacro %}
|
||||
|
||||
{# ------------------------------------------------------------------------------------------ #}
|
||||
|
||||
<span class="footer-scan">Scan: {{ cover.scan_id }}</span>
|
||||
<span class="footer-date">{{ cover.footer_date }}</span>
|
||||
|
||||
<div class="cover-mark">
|
||||
<img src="{{ cover.logo }}" alt="CipherCell" />
|
||||
</div>
|
||||
|
||||
<div class="cover-title">{{ cover.title }}</div>
|
||||
|
||||
{{ facts(cover.identity) }}
|
||||
|
||||
{% if cover.severity_ledger %}
|
||||
<h2>{{ cover.severity_ledger.title }}</h2>
|
||||
<table class="ledger">
|
||||
{% for row in cover.severity_ledger.rows %}
|
||||
<tr{% if row.total %} class="total"{% endif %}>
|
||||
<td>{{ row.label }}</td>
|
||||
<td>{{ row.count }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
|
||||
{% if scan %}
|
||||
<h1 style="break-before: page">{{ scan.title }}</h1>
|
||||
{{ facts(scan.overview, wide=true) }}
|
||||
|
||||
{% for stage in scan.stages %}
|
||||
<h3>{{ stage.title }}</h3>
|
||||
{{ facts(stage.rows, wide=true) }}
|
||||
{% if stage.table %}{{ grid(stage.table) }}{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if project %}
|
||||
<h1 style="break-before: page">{{ project.title }}</h1>
|
||||
{{ facts(project.overview, wide=true) }}
|
||||
|
||||
{% if project.languages %}
|
||||
<h2>{{ project.languages.title }}</h2>
|
||||
<table class="ledger">
|
||||
{% for row in project.languages.rows %}
|
||||
<tr{% if row.total %} class="total"{% endif %}>
|
||||
<td>{{ row.label }}</td>
|
||||
<td>{{ row.share }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if summary %}
|
||||
<h1>{{ summary.title }}</h1>
|
||||
{{ facts(summary.overview, wide=true) }}
|
||||
|
||||
{% for block in summary.distributions %}
|
||||
<h2>{{ block.title }}</h2>
|
||||
{{ distribution(block.rows, block.legend) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if critical %}
|
||||
<h2 style="break-before: page">{{ critical.title }}</h2>
|
||||
{{ grid(critical.table) }}
|
||||
{% endif %}
|
||||
|
||||
{% for section in sections %}
|
||||
<h1{% if section.new_page %} style="break-before: page"{% endif %}>{{ section.title }}</h1>
|
||||
|
||||
{% for group in section.groups %}
|
||||
<h2>{{ group.title }}</h2>
|
||||
{% if group.note %}<p class="note">{{ group.note }}</p>{% endif %}
|
||||
|
||||
{% for entry in group.cards %}
|
||||
{{ card(entry.title, entry.rows) }}
|
||||
{% endfor %}
|
||||
|
||||
{% if group.table %}
|
||||
{% if group.table.title %}<h2>{{ group.table.title }}</h2>{% endif %}
|
||||
{{ grid(group.table) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
Reference in new issue
Block a user