Skip to content

feat(cv): let a printed document set its typeface, course widths and sourcemaps - #18

Merged
eduardstan merged 3 commits into
mainfrom
fm/lp-cv-layout-configurable
Jul 30, 2026
Merged

eduardstan merged 3 commits into
mainfrom
fm/lp-cv-layout-configurable

Conversation

@eduardstan

Copy link
Copy Markdown
Owner

Intent

Teach ledgerpress's shared printed-CV layout (cv/preamble.tex) to take instructions from a document instead of hard-coding a look, so that eduardstan.github.io can drop its forked cv/cv.tex and adopt the shared layout while its printed CV does not visibly change. That fork is the largest recurring merge conflict between the two repositories; this task is only the template half, a separate task switches the site over.

Exactly three differences were to be parameterised, and no more:

  1. Typeface. The template uses fontspec + TeX Gyre Pagella; the site uses the NFSS package cfr-lm. These are different mechanisms, so this is deliberately NOT one macro taking a font name: \cvtypeface carries the whole font setup block, because \setmainfont takes a font argument and \usepackage{cfr-lm} takes none, and no single value spans both. That is a considered tradeoff, not an oversight.
  2. Course-table geometry. \cvcoursecols receives the generated equal-width column specification as feat: launch ledgerpress academic publishing template #1 and returns the specification to use; the default returns it unchanged. A new cvcoursetable counter is stepped in \cvcourses so a document can vary widths per table (the site's first course table is 3mm wider in its second column than the two below it). The counter is stepped OUTSIDE the table on purpose: tabularx reads its body more than once, so a counter stepped inside would count wrong. The result is \edef-expanded through a new \cvcoursesprint helper before the table sees it, because the array package rejects a macro found in a column specification with 'Illegal pream-token' - this was confirmed empirically by a failing build, not assumed.
  3. Bibliography tidying. biblatex accepts exactly one \DeclareSourcemap, so a document adding its own would silently lose the template's two. \cvsourcemaps is expanded inside the template's existing \maps block, so a document's \map blocks run after the template's. The site's four sourcemaps were deliberately NOT promoted into the template as everyone's default: they are specific to one person's bibliography.

Hard constraints that were required and met:

  • The bundled example's printed output must be unchanged. All three settings are \providecommand'd to exactly what the template prints today, the template itself sets none of them, and all three documents (cv/cv.tex, cv/short.tex, cv/teaching.tex) were rebuilt and checked against data/cv-baseline/. Their pdftotext -layout SHA-256 hashes match the recorded baselines exactly. npm run check, npm test and npm run check:maintainer all exit 0.
  • No adopter-facing check may assert any of these settings, directly or by asserting rendered output that depends on them. This is a standing rule in AGENTS.md, with scripts/check-deployment-base.mjs as the worked example. So NO new check or test was added for the three settings - that absence is deliberate and required, not missing test coverage. A repository that sets none of the three must build, which npm run check:adopter already proves. Adding an assertion on a typeface, a column width or a sourcemap would violate the repository's own rule.
  • Three settings, not a theming system. No colour scheme, no spacing scale, no style registry, no config file, no flag or manifest surface, and no website variant of the mechanism. AGENTS.md now records that the set must not grow without the same evidence: a real fork a shared layout otherwise cannot absorb.
  • Documentation goes where an adopter meets it, following existing convention: README.md's 'Make it yours after the first green build' section gained a subsection 'Three printed-CV settings a document carries itself', and AGENTS.md gained a short entry pointing at it. No new documentation location was invented.

Verification of the site's look was done by building a throwaway cv/proof.tex carrying the site's concrete values (cfr-lm + T1 fontenc, its two hand-tuned column width sets keyed on the counter, its four sourcemaps) and confirming it compiles and takes effect - cfr-lm and pplr8t/pplb8t/pplri8t in the log, visibly re-tuned course columns in the extracted text, the four extra maps in the .bcf. All three reproduce. That proof file was deleted and is not part of the change.

Two findings for the follow-on site task, deliberately left unimplemented here because they are outside the three-and-no-more scope: (a) \headerfontiii is a fourth thing the site changes (template \rmfamily vs site \fontfamily{ppl}\selectfont) but it needs no new mechanism because it is already \renewcommand-able after \input{preamble.tex}; (b) the site's fork also hard-codes the course header row wording, which the template now derives from the record's row keys - that is record curation, not layout.

The PR description must state explicitly the concrete settings values that reproduce the site's current look - typeface cfr-lm, its column widths, its four sourcemaps - and state plainly whether each one is achievable through what was built.

What Changed

  • cv/preamble.tex now \providecommands \cvtypeface, holding the whole font setup block rather than a font name (\setmainfont takes an argument, \usepackage{cfr-lm} takes none, so no single value spans both). A document defines it before \input{preamble.tex}; the default still loads fontspec + TeX Gyre Pagella. eduardstan.github.io's \newcommand{\cvtypeface}{\usepackage{cfr-lm}\usepackage[T1]{fontenc}} reproduces its look through this — achievable. Its fourth difference, \headerfontiii (\fontfamily{ppl}\selectfont), needs no new mechanism: it is already \renewcommand-able after \input{preamble.tex}.
  • \cvcourses steps a new cvcoursetable counter outside the table (tabularx reads its body more than once) and passes the generated equal-width column specification through \providecommanded \cvcoursecols, \edef-expanded via a new \cvcoursesprint helper because array rejects an unexpanded macro in a column specification with Illegal pream-token. The default returns #1 unchanged. The site's two hand-tuned sets — P{3.1cm} P{3.8cm} Y P{1.2cm} for cvcoursetable=1, P{3.1cm} P{3.5cm} Y P{1.2cm} otherwise — are expressible as a single \ifnum\value{cvcoursetable}=1 definition and print at the intended widths — achievable.
  • \cvsourcemaps (empty by default) expands inside the template's existing \maps block, so a document's \map blocks run after the template's two instead of silently replacing them — biblatex accepts exactly one \DeclareSourcemap. The site's four sourcemaps all apply, in order after the template's, without promoting them into the template as anyone's default — achievable. README.md gained "Three printed-CV settings a document carries itself" under "Make it yours" and AGENTS.md a pointer recording that the set must not grow into a theming system; no check asserts any of the three, per the repository's standing rule, and all three baselines rebuild byte-for-byte unchanged.

Risk Assessment

✅ Low: Branch is three \providecommand-guarded layout hooks whose defaults reproduce today's output token-for-token plus documentation, and the only round-1 finding was a one-word README wording fix that is now applied correctly with no source change.

Testing

Rebuilt all three printed documents and proved the bundled example is untouched (baseline text hashes match and cv.pdf is pixel-identical to the recorded baseline PDF), then reconstructed the author's deleted proof document with the site's concrete cfr-lm typeface, counter-keyed course-column widths and four sourcemaps and confirmed each setting reaches the built PDF and the .bcf, including a probe map that visibly removed URLs from the printed bibliography while the template's own maps still applied; targeted node tests and the generated-data freshness gate also pass, and no new check asserts any of the three settings as the intent requires. The example record exposes two harmless notes rather than defects: the site's four maps are no-ops on it (no entry carries both doi and url, and it has no issn/eprint/series fields), and 8-bit cfr-lm cannot print that record's macrons — neither affects the shipped defaults. Node dependencies were missing and were installed to run the checks, then removed along with every build artifact, leaving the worktree clean.

  • Evidence: Side-by-side: template defaults vs the site's values through the new settings (local file: /tmp/no-mistakes-evidence/01KYT4TC0HJS13GEN2YK92JZ0G/typeface-and-columns-side-by-side.png)
  • Evidence: Course-table geometry: default equal widths vs per-table hand-tuned widths (local file: /tmp/no-mistakes-evidence/01KYT4TC0HJS13GEN2YK92JZ0G/course-columns-per-table.png)
Evidence: Bundled example unchanged: baseline hashes and pixel diff

pdftotext -layout SHA-256, built PDF vs data/cv-baseline/<name>-baseline.txt: cv/cv.pdf f52c70917b1b5d85c2f830f9a22b7e109c5b5b031280f239d736305aedbe8d0e (matches) cv/short.pdf 92b41fffe9f82491717fdedaf0932971e4954a8052e88938e0c1b4069402a190 (matches) cv/teaching.pdf 6b9b2bd2ad5db11eb05a6c53518a7bc009e3d1a9cd5820b7adafdfb123175c0e (matches) npm run check:maintainer -> exit 0 (all three baselines) Pixel comparison, built cv/cv.pdf vs data/cv-baseline/cv-baseline.pdf at 110 dpi: page 1: 0 differing pixels page 2: 0 differing pixels page 3: 0 differing pixels

Bundled example unchanged — all three documents rebuilt from this branch.

pdftotext -layout SHA-256, built PDF vs data/cv-baseline/<name>-baseline.txt:
  cv/cv.pdf built vs data/cv-baseline/cv-baseline.txt
    built    f52c70917b1b5d85c2f830f9a22b7e109c5b5b031280f239d736305aedbe8d0e
    baseline f52c70917b1b5d85c2f830f9a22b7e109c5b5b031280f239d736305aedbe8d0e
  cv/short.pdf built vs data/cv-baseline/short-baseline.txt
    built    92b41fffe9f82491717fdedaf0932971e4954a8052e88938e0c1b4069402a190
    baseline 92b41fffe9f82491717fdedaf0932971e4954a8052e88938e0c1b4069402a190
  cv/teaching.pdf built vs data/cv-baseline/teaching-baseline.txt
    built    6b9b2bd2ad5db11eb05a6c53518a7bc009e3d1a9cd5820b7adafdfb123175c0e
    baseline 6b9b2bd2ad5db11eb05a6c53518a7bc009e3d1a9cd5820b7adafdfb123175c0e

npm run check:maintainer  -> exit 0 (all three baselines)

Pixel comparison, built cv/cv.pdf vs the recorded data/cv-baseline/cv-baseline.pdf at 110 dpi:
  page 1: 0 differing pixels
  page 2: 0 differing pixels
  page 3: 0 differing pixels
Evidence: Typeface and sourcemap settings taking effect (log + .bcf + printed bibliography)

== 1. TYPEFACE (\cvtypeface) == cv.tex (template default): Package: fontspec 2022/01/15 / TeXGyrePagella proof.tex (site values): Package: cfr-lm 2015/02/01 / faces clm2j clmbx2j8t12 clmr2ij8t9 clmr2j8t10 clmr2j8t9 == 3. SOURCEMAPS (\cvsourcemaps), user-level \maps block in the .bcf biber reads == cv.bcf user maps: 2 (template's two) proof.bcf user maps: 6 (template's two, then the document's four, in that order) -- does a document \map actually reach the printed bibliography? -- proof.tex with the site's four maps: 3 URLs printed (none of the four bite on the bundled record: no entry has both doi and url, and it has no issn/eprint/series) proof.tex plus a probe \map{\step[fieldset=url, null]}: 0 URLs printed the template's own two maps still applied in the same build

== 1. TYPEFACE (\cvtypeface) ==
cv.tex    (template default): Package: fontspec 2022/01/15 / TeXGyrePagella
proof.tex (site values):      Package: cfr-lm 2015/02/01 / faces clm2j clmbx2j8t12 clmr2ij8t9 clmr2j8t10 clmr2j8t9 

== 3. SOURCEMAPS (\cvsourcemaps), user-level \maps block in the .bcf biber reads ==
cv.bcf    user maps: 2  (template's two)
proof.bcf user maps: 6  (template's two, then the document's four)

    <bcf:maps datatype="bibtex" level="user">
      <bcf:map>
        <bcf:map_step map_field_set="abstract" map_null="1"/>
        <bcf:map_step map_field_set="selected" map_null="1"/>
        <bcf:map_step map_field_set="preview" map_null="1"/>
        <bcf:map_step map_field_set="abbr" map_null="1"/>
        <bcf:map_step map_field_set="bibtex_show" map_null="1"/>
        <bcf:map_step map_field_set="html" map_null="1"/>
        <bcf:map_step map_field_set="pdf" map_null="1"/>
        <bcf:map_step map_field_set="code" map_null="1"/>
        <bcf:map_step map_field_set="altmetric" map_null="1"/>
        <bcf:map_step map_field_set="dimensions" map_null="1"/>
      </bcf:map>
      <bcf:map>
        <bcf:map_step map_field_source="note" map_match="\AAccessed\son\sYYYY-MM-DD\.?\Z" map_final="1"/>
        <bcf:map_step map_field_set="note" map_null="1"/>
      </bcf:map>
      <bcf:map>
        <bcf:map_step map_field_source="doi" map_final="1"/>
        <bcf:map_step map_field_set="url" map_null="1"/>
      </bcf:map>
      <bcf:map>
        <bcf:map_step map_field_set="issn" map_null="1"/>
      </bcf:map>
      <bcf:map>
        <bcf:map_step map_field_set="eprint" map_null="1"/>
      </bcf:map>
      <bcf:map>
        <bcf:map_step map_field_set="series" map_null="1"/>
      </bcf:map>
    </bcf:maps>

-- does a document \map actually reach the printed bibliography? --
proof.tex with the site's four maps:                          3 URLs printed
  (none of the four bite on the bundled record: no entry has both doi and url, and it has no issn/eprint/series)
proof.tex plus a probe \map{\step[fieldset=url, null]}:        0 URLs printed
  the template's own two maps still applied in the same build (abstracts absent, access notes tidy)
Evidence: Course-table column text, default vs both hand-tuned tables
== 2. COURSE-TABLE GEOMETRY (\cvcoursecols + cvcoursetable counter) ==

-- cv.pdf: template default, generated equal-width spec 'Y Y Y Y' returned unchanged --
    Course                              Programme                       Topics                       Points
    GEOL 273                            B.Sc. Geology                   Palaeoclimate archives;      18
                                                                        proxy calibration
    GEOL 472                            B.Sc. (Hons)                    Marine cores; age-depth      18
                                                                        modelling

-- proof.pdf table 1 (cvcoursetable = 1): P{3.1cm} P{3.8cm} Y P{1.2cm} --
    GEOL 273                 B.Sc. Geology                Palaeoclimate archives; proxy calibration                     18
    GEOL 472                 B.Sc. (Hons)                 Marine cores; age-depth modelling                             18
    OCEN 405                 M.Sc. Oceanography           Southern Ocean circulation; uncertainty                       20

-- proof.pdf table 2 (cvcoursetable = 2): P{3.1cm} P{3.5cm} Y P{1.2cm}  (2nd column 3mm narrower) --
    GEOL 273                 B.Sc. Geology             Palaeoclimate archives; proxy calibration                         18
    GEOL 472                 B.Sc. (Hons)              Marine cores; age-depth modelling                                 18
    OCEN 405                 M.Sc. Oceanography        Southern Ocean circulation; uncertainty                           20
Evidence: Throwaway proof document used for verification (not part of the change; deleted from the worktree)
% -----------------------------------------------------------------------------
% THE FULL CV: WHICH SECTIONS IT CURATES, AND IN WHAT ORDER.
%
% Styling, packages and the section macros are in cv/preamble.tex; the name and
% contact block in cv/header.tex; the supervision table in cv/supervision.tex.
% All three are shared with cv/short.tex and cv/teaching.tex.
%
% Most sections below are one \cvpart line each, placing the sections this
% document curates - their heading, their order, their setting. Sections with
% custom layout use guarded blocks or shared body fragments. \cvAutoSections at the end then prints
% every remaining section of content/cv.yaml, so a section added to the record
% appears here with no edit to this file. \cvpart also takes an optional entry
% count, \cvpart[3]{...}{Appointments}, which the variants use and this document
% does not: the full CV prints every entry it has.
%
% Build:  latexmk -xelatex -cd cv/cv.tex      (xelatex is required: academicons)
% -----------------------------------------------------------------------------
% THROWAWAY PROOF DOCUMENT - not part of the change, deleted after testing.
% Carries the concrete values eduardstan.github.io's forked cv/cv.tex uses.
\newcommand{\cvtypeface}{%
  \usepackage{cfr-lm}\usepackage[T1]{fontenc}%
}
\newcommand{\cvcoursecols}[1]{%
  \ifnum\value{cvcoursetable}=1 P{3.1cm} P{3.8cm} Y P{1.2cm}%
  \else P{3.1cm} P{3.5cm} Y P{1.2cm}\fi}
\newcommand{\cvsourcemaps}{%
  \map{\step[fieldsource=doi, final]\step[fieldset=url, null]}%
  \map{\step[fieldset=issn, null]}%
  \map{\step[fieldset=eprint, null]}%
  \map{\step[fieldset=series, null]}%
  % probe: a fifth map whose effect is visible on THIS record
  \map{\step[fieldset=url, null]}%
}
\input{preamble.tex}

\begin{document}
\headerfontiii

\input{header.tex}

% The ungrouped declaration keeps the rest of the CV at the compact body size.
% Using \small{ here would leave a group open at \end{document}.
\ifx\cvShortBio\cvempty\else
\section{\textbf{Short Bio}}
\fi
\vspace{1mm}
\small
\cvShortBio
\vspace{-2mm}

\ifx\cvFocus\cvempty\else
\section{\textbf{Research Focus}}
\vspace{1mm}
\small{
\cvFocus
}
\vspace{-2mm}
\fi

\cvpart{Academic Appointments / Experience}{Appointments}

\cvpart{Education}{Education}

\cvpart{Teaching}{Teaching}

\cvpartflush{Editorial, Reviewing \& Conference Service}{Service}

\cvpartflush{Research Projects}{Projects}

\cvpartflush{Awards \& Scholarships}{Awards}

% The supervision table, shared with cv/teaching.tex. Above \cvAutoSections,
% like every other \cvdeclare, so the record's sequence does not repeat it.
\input{supervision.tex}

\cvdeclare{Languages}
\ifnum\cvLanguagesCount>0
\ifnum\cvLanguagesPrinted>0
\section{\textbf{Additional Information}}
\vspace{-0.4mm}
\small{
\textbf{Languages:} \cvLanguagesInline
}
\fi
\fi

% Every section of content/cv.yaml the lines above did not place, in the order the
% record writes them. This is the line that makes a new section print without a
% LaTeX edit: nothing here names one.
%
% Every \cvpart, \cvpartflush and hand-written \cvdeclare MUST stay above this
% line: \cvautopart skips a key only once \cvdeclare has marked it laid out, so a
% section moved below would print twice, once under each heading. The cv.tex
% contract test in scripts/build-cv-data.test.mjs enforces the ordering.
\section{\textbf{Second course table (cvcoursetable = 2)}}
\cvpart{Teaching again}{Teaching}
\cvAutoSections

\cvdeclarebib{Talks}
\ifnum\cvTalksCount>0
\section{\textbf{Talks \& Presentations} \hfill \textcolor{darkblue}{\scriptsize \cvTalksKey}}

\begin{refsection}[../content/talks.bib]
\nocite{*}

\cvTalksSections

\end{refsection}
\fi

\cvdeclarebib{Publications}
\ifnum\cvPublicationsCount>0
\section{\textbf{Publications} \hfill \textcolor{darkblue}{\scriptsize \cvPublicationsKey}}

\begin{refsection}[../content/publications.bib]
\nocite{*}

% Every section declared under `publications:` in content/cv.yaml, in the order
% it is written there. A section whose filter matches nothing prints nothing at
% all - no heading, no gap - so an adopter whose career is books declares one
% and it appears with the first entry.
\cvPublicationsSections

\end{refsection}
\fi

\vspace{5mm}
{\footnotesize
\cvFooter
}

\end{document}
Evidence: Built PDFs: template defaults and the proof carrying the site's values
%PDF-1.5
%

... [70558 bytes truncated] ...


endstream
endobj
startxref
69862
%%EOF
- Evidence: Page renders used for the pixel comparison (built vs recorded baseline) (local file: /tmp/no-mistakes-evidence/01KYT4TC0HJS13GEN2YK92JZ0G/px)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 1 issue found → auto-fixed ✅
  • ℹ️ README.md:305 - README says the three settings are "unset by default", but cv/preamble.tex \providecommand's all three (lines 76, 328, 416) and AGENTS.md states "Each is \providecommand'ed to today's look". An adopter probing with \ifdefined\cvtypeface after \input{preamble.tex} would find it defined. The rest of the sentence ("the template's own look is the default") is correct; only "unset" is wrong. Suggest "each defaults to what the template prints today".

🔧 Fix: docs: fix README claim that the three settings are unset
✅ Re-checked - no issues remain.

✅ **Test** - passed

✅ No issues found.

  • latexmk -xelatex -cd cv/cv.tex, cv/short.tex, cv/teaching.tex (all three rebuilt from this branch)
  • npm run check:maintainer — exit 0 for all three baselines
  • pdftotext -layout &lt;pdf&gt; | sha256sum vs data/cv-baseline/&lt;name&gt;-baseline.txt for cv, short, teaching — all match
  • pdftoppm -r 110 -png + compare -metric AE of built cv/cv.pdf vs data/cv-baseline/cv-baseline.pdf — 0 differing pixels on pages 1-3
  • Manual: built a throwaway cv/proof.tex defining \cvtypeface (cfr-lm + T1 fontenc), \cvcoursecols (P{3.1cm} P{3.8cm} Y P{1.2cm} for cvcoursetable=1, P{3.5cm} second column otherwise) and \cvsourcemaps (four \map blocks) before \input{preamble.tex}
  • Manual: grep &#39;Package: cfr-lm&#39; cv/proof.log and clm* face names vs fontspec/TeXGyrePagella in cv.log
  • Manual: user-level &lt;bcf:maps&gt; block of cv/proof.bcf (6 maps: template's 2 then the document's 4, in order) vs cv/cv.bcf (2)
  • Manual: pdftotext -layout of proof.pdf showing the two course tables printing at different column widths
  • Manual probe: added \map{\step[fieldset=url, null]} and rebuilt — printed URLs went 3 to 0 while the template's own maps still applied
  • Manual: rebuilt with README.md's documented package order \usepackage{cfr-lm}\usepackage[T1]{fontenc} — clean build, cfr-lm still in effect
  • node --test scripts/build-cv-data.test.mjs scripts/check-cv-baseline.test.mjs — 50 pass
  • node scripts/build-cv-data.mjs --check — generated data fresh
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

eduardstan and others added 3 commits July 30, 2026 20:31
The printed layout in cv/preamble.tex hard-codes three things that an adopter
with a real bibliography and real course names has to fork the file to change.
eduardstan.github.io carries exactly such a fork, and it is the largest
recurring merge conflict between the two repositories.

Three \providecommand hooks, each read where it is used and each defaulting to
what the template prints today:

- \cvtypeface carries the whole font setup, not a font name. fontspec's
  \setmainfont and an NFSS font package are different mechanisms and no single
  argument spans them, so the macro holds either.
- \cvcoursecols takes the generated equal-width column specification and returns
  the one to use. The tables are numbered by a new cvcoursetable counter stepped
  outside the table, because tabularx reads its body more than once. The result
  is expanded before array sees it, which array requires of a column
  specification.
- \cvsourcemaps adds \map blocks to the one \DeclareSourcemap biblatex allows,
  so a document can tidy its own entries without losing the template's two.

A document defines them before its \input{preamble.tex}. The template sets none,
no check asserts any, and the three baselines are unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@eduardstan
eduardstan merged commit 1b9056d into main Jul 30, 2026
3 checks passed
eduardstan added a commit that referenced this pull request Jul 31, 2026
…sourcemaps (#18)

* feat(cv): let a document set its typeface, course widths and sourcemaps

The printed layout in cv/preamble.tex hard-codes three things that an adopter
with a real bibliography and real course names has to fork the file to change.
eduardstan.github.io carries exactly such a fork, and it is the largest
recurring merge conflict between the two repositories.

Three \providecommand hooks, each read where it is used and each defaulting to
what the template prints today:

- \cvtypeface carries the whole font setup, not a font name. fontspec's
  \setmainfont and an NFSS font package are different mechanisms and no single
  argument spans them, so the macro holds either.
- \cvcoursecols takes the generated equal-width column specification and returns
  the one to use. The tables are numbered by a new cvcoursetable counter stepped
  outside the table, because tabularx reads its body more than once. The result
  is expanded before array sees it, which array requires of a column
  specification.
- \cvsourcemaps adds \map blocks to the one \DeclareSourcemap biblatex allows,
  so a document can tidy its own entries without losing the template's two.

A document defines them before its \input{preamble.tex}. The template sets none,
no check asserts any, and the three baselines are unchanged.

* no-mistakes(review): docs: fix README claim that the three settings are unset

* no-mistakes(document): note the three document settings in README variant list

---------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant