Adds a button that, when clicked, gathers every question() and
student_info() answer currently on the page – each already saved to
the browser's localStorage as the reader worked through the tutorial
– into a single readable JSON file and downloads it. This happens
entirely in the reader's browser; there is no server to submit to, so
this is meant for a reader to save and turn in themselves (e.g. attach
to an email or upload to an LMS).
Details
The download's answers array is one flat list: every question() plus
every {webr} code exercise, each as a { id, answer } pair keyed by
the widget's (or exercise's) stable id. A question never submitted has
answer: null; a choice question's answer is an array of the picked
options; an image-paste reflection's answer is the pasted screenshot
as a PNG data-URL string.
A {webr} exercise appears only under the condition quarto-live itself
requires to keep a record of the reader's code at all: #| persist: true (already the convention every bundled tutorial follows). An
exercise without persist: true has no saved copy of the reader's code
anywhere – learnr2 included – so it can't appear in the download;
this is a structural limit of quarto-live's own editor, not something
download_answers_button() chooses to skip.
The download includes a metadata block (timestamp, timezone, browser
info, and a random per-device id persisted across the reader's visits)
and a SHA-256 integrity hash over the content. Check a downloaded file
with verify_submission(). This is tamper-evidence, not proof of
identity: since everything runs in the reader's own browser with no
server-held secret, a technical reader could reproduce the hash
themselves. What it reliably catches is editing the file afterward (e.g.
changing a wrong answer to a right one before turning it in).