How it was made
The grown-up page. Each claim names its limits and a way to check it.
The short version
Your browser encrypts each file with AES-256-GCM before upload. We store ciphertext and never receive the key. Everything after # is the key. Browsers don't send it to any server, including ours.
We delete the ciphertext from our disk within a minute of its exit. If the exit was a download, we wait for it to finish (at most ). We keep a note that the link existed, so we can tell you why it's gone. We never had the key, so any leftover bytes are noise.
Every exit goes on the public record: we add it to SealLog on the Ootle at the next checkpoint (within ). It proves we said we deleted it, publicly and permanently. It can't prove we kept no copy.
Who sees what
Our server
We see a padded size (rounded up so the exact size stays hidden: at least 1 KB, and at most 12% over for anything bigger), the hour it arrived, its exit rule and how often it's opened. Not the name, the type, the contents or the key.
Our server sees your IP address while you're connected. We don't write it to disk: rate limits use a keyed hash, kept in memory, with a key that changes every day.
The Tari™ chain
The chain shows an output with a hidden amount, a hidden owner and an encrypted memo. The fee is public. Our courier payments all come from one wallet with the same fee, so someone watching could group them as “sent by bye”, but not see to whom.
The chain shows an output with a hidden amount, a hidden owner and an encrypted memo. The fee is public. Sends from your browser spend a grant from our sponsor wallet, then each send's change, so anyone reading the Ootle can link them to each other and to our sponsor wallet, but not see to whom or how much.
In relay mode we post the payment for you, so we learn the address you send to, never the key.
Whoever has the link
The file, as many times as its rule says (once, by default). The link is the key: anyone who gets the full link can open it until it's gone.
A view key
A view key can't spend, but it can read everything sent to this address, including files. Give it only to someone allowed to see those.
For files sent to a locker, the view-key screen lists arrivals and opens no file. Files sent to another wallet open with its view key.
For space you rent from us we see the amount, because we're the seller. Nobody else does.
Every party, fact by fact
| Our server | Anyone watching the Ootle | Someone with the full link | The person you send it to | |
|---|---|---|---|---|
| File contents | no (ciphertext) | no | yes | yes |
| Name and type | no (encrypted inside) | no | yes | yes |
| Exact size | no (a padded bucket) | no | yes | yes |
| The key | no | no | yes (the link is the key) | yes |
| That a file exists, its arrival hour, its rule, its opens | yes | counts only, in steps of 64: records (stored files plus exits) per checkpointno | partly (state, opens left) | does not apply |
| Your IP address | while you're connected; not written to disk | no (Tari's indexer sees it only if you press “Check it on Tari's indexer”) | no | no |
| Who you send to | yes for every send and dead-drop delivery, while it's sent; then the job is scrubbedsends from your browser: no; sends our relay posts (before your browser's wallet has its grant) and dead-drop deliveries: yes, while they're sent | no (a one-time stealth address) | does not apply | they know it's them |
| That we sent a payment | yes | yes for relay sends: one wallet, one fee; sends from your browser trace back to our sponsor wallet's grant, and to each other through their change | does not apply | does not apply |
| Payment amounts | for space rented from us, because we're the seller | no (a Pedersen commitment) | does not apply | does not apply |
| The network fee | does not apply | public | does not apply | does not apply |
| SealLog (hashes, counts, times) | yes | public by design, written by the same key that holds our public tTARI | does not apply | does not apply |
Our server, in detail
- Sees and stores
- Ciphertext and its padded size; the hour an item arrived and when it left; expiry and view counts, and the time of a link's first open (shown only to its owner); the exit rule (link or password); for lockers: a random-looking locker id, a hash of its login key, the first and last active day, how many distinct days it was active, quota and packs bought; invoices (pack, amount, status) and the chain outputs that paid them; dead drops: the drop's Tari address, its label, its tag and daily counters; abuse reports; notes about ended links (state and day).
- Sees, never stores
- Every uploader's and every opener's IP address, live (so at the moment it happens we could link who uploaded a link with who opened it); the login key at sign-in; access tokens (hashed on arrival); which drop a file was left in, and the submitter's IP; the destination Tari address of every send, the sealed 125-byte blob, which locker sent it, and by timing which link it carries, kept in the job until sent and then scrubbed; that your locker submitted a transaction, not to whom; for dead-drop deliveries, the drop's address while the delivery is sent.
- Never sees
- File names, types, contents and real sizes; file keys, link secrets, passwords, seeds or any private key; your locker's Tari address, unless you make a drop or a relay send goes to it; who you send a file to, when your browser's wallet sends it (until its grant arrives, our relay sends it and learns the address while it's sent); which chain outputs your browser can open (everyone downloads the same copy of the chain); who shares with whom (there is no sharing inside bye).
Everyone else
- A network observer
- That you talk to us, timing, and padded transfer sizes. Nothing inside TLS.
- Someone with only the link's path (no
#) - That a link exists, whether it needs a password, and its state; once it has ended, why and on what day, and its exit receipt: the file's id and exit hour, and through the log which checkpoint windows its arrival and exit fell in. Not the key, the contents, the name, the real size or the open count.
- A view-key holder
- Every delivery and payment to that address: amount, time and the memo's link text. Not the files locked to the locker, and it can't spend. The one exception: files a sender sealed with “The recipient uses another Ootle wallet” do open with the view key, and the send screen says so.
- The public, through our live numbers
- The free quota; our disk's size and free space, rounded; whether uploads or the Tari features are paused; how many lockers were active recently, once there are enough of them; SealLog's latest checkpoint; how many minutes ago someone last locked a file; and for up to 24 recent files, each at least an hour old, a coarse size and an exit rule, never whether one was opened, only when at least 8 exist in the last week. Nothing per person, but someone who knows a file's size and rule may recognise it there.
- Our host (Hostinger)
- Everything our server stores, plus the disk and any snapshots it keeps; in principle, live memory.
The locks
- Files: AES-256-GCM in your browser, in chunks; size padded so the exact size stays hidden.
- The key: in the link after #, or sealed to a Tari address inside a stealth payment's encrypted memo.
- Secret words: stretched in your browser with PBKDF2, rounds; we slow down guessing after wrong tries.
- Photos: location and camera data removed before locking, unless you keep the original.
The cryptography, in full
Everything that touches a file or a key runs in your browser, with your browser's own WebCrypto. The server never receives a file key, a link's secret, a password or your seed. At sign-in it sees your login key and keeps only its SHA-256.
- Files: a fresh random 32-byte key per file. The content is padded with Padmé (at least 1 KB, at most 12% over above that), cut into 4 MB chunks and encrypted with AES-256-GCM. Each chunk's nonce holds its index and a “last chunk” flag, and every chunk authenticates the file's header, so reordering, truncation and extension all fail.
- Metadata: the name, type and real size are encrypted separately, also with AES-256-GCM, padded to a multiple of 256 bytes.
- Keys from keys: HKDF-SHA256 with a separate label for every purpose, so one derived key reveals nothing about another.
- Links: every link has its own 32-byte secret, after the
#. It unwraps the file key and derives an access token; our server stores only the SHA-256 of that token. - Passwords: PBKDF2-SHA256, rounds, combined with the link's secret by default (link + password), so a copy of our database isn't enough to guess it.
- Lockers: one 32-byte seed made in your browser, kept in its storage, and backed up as your recovery code or key file. Everything else is derived from it: the login key (we store its SHA-256), the locker's Tari keys, a separate wallet key, and the dead-drop tags. There is no email and no password with us.
- Safety code: 12 emoji (96 bits) derived from a locker's public keys, so two people can compare a locker out loud.
- Proof of work: SHA-256 with a number of leading zero bits, instead of a captcha. Your browser solves it in a background worker.
- Photos: location and camera data are removed from JPEG, PNG and WebP files before encryption, unless you choose to keep the original.
Sealing a file to a Tari address
When you send a file to a Tari address, your browser seals the link's secret to that address's two public keys, the owner key and the view key, using the official Tari library for the key agreement. The sealed blob is 125 bytes, and it travels as the memo of a stealth payment.
- Why a view key can't open your files: the seal needs both the owner key and the view key to open. A view key alone shows that a delivery arrived, its amount and its memo text, but not the file.
- The exception, labelled: a sender can choose “The recipient uses another Ootle wallet”. That seal uses the view key only, so anyone with that view key can open the file, and the send screen says so.
- Who posts the payment: our relay. We post the payment for you, so we learn the address you send to, never the key. The server writes the memo from its own address; a client supplies only the sealed blob.
- Who posts the payment: your browser, once its wallet holds the testnet grant our sponsor wallet sends when a locker opens: it builds, signs and pays for it, and our server passes it to the network without learning who it's for. Until the grant arrives (a minute or two), our relay posts the send and learns the address while it's sent. A browser send spends that grant, so the chain links your sends to the sponsor wallet and to each other. Dead-drop deliveries still go through our relay, because a drop's address is public by design.
Who could attack a link, and what stops them
| Adversary | Can | What stops them | What remains |
|---|---|---|---|
| Network observer | see TLS metadata | HTTPS only, HSTS, Padmé size buckets | timing and volume |
| A curious or compromised server (including our host) | read the database and the stored files, change responses, watch IP addresses live | everything is encrypted in the browser; tokens and verifiers are hashed; no public keys or locker addresses stored for logins; no sharing graph; each chunk is authenticated together with its header | can serve malicious JavaScript (see verify); can refuse service; sees the metadata listed on How it works; knows each relay send's destination; can ignore a deletion and keep ciphertext, which is useless without the key |
| Someone with only the link's path | ask for its status | the key lives only after the #; opening needs an access token derived from it; link + password adds a link proof | learns that a link exists, and its state |
| Password guesser, online | try passwords | the access token comes from the password; growing pauses; proof of work; only holders of the full link can count as wrong passwords | slow guessing against weak password-only links |
| Password guesser, with a copy of our database | guess password-only links offline | PBKDF2-SHA256 with rounds; link + password is the default, and password-only links come with a warning | weak password-only secrets |
| Chain observer | read all public state | stealth outputs, encrypted memos, one fee and one amount for every relay send, decoy sends | the fee and the transaction graph are public; relay sends are recognisable as ours; sends from a browser spend a grant from our sponsor wallet and then their own change, so they can be linked to each other and to us |
| A view-key holder | read arrivals, amounts and memo text | files locked to a locker need its owner key too | files sent with “The recipient uses another Ootle wallet” open with the view key (labelled at send time) |
| Phishing through our relay | make our wallet send a link | the server writes every memo our relay sends, from its own address; a client supplies only a 125-byte sealed blob; sends need a locker; drop deliveries only go to the drop's own address | someone can send unwanted bye deliveries to an address: daily caps, closable drops, a separate inbox section, no automatic preview, a warning before programs. Sends from browsers carry a memo the browser wrote, so a modified client can put any text on chain to any address, within one sponsor grant a day per locker, and two per network; inboxes show a memo that isn't exactly a bye link as plain text, never as a link |
| Griefer | fill storage, push proof of work up, drain daily budgets, lock links | reserved lanes for small and anonymous files, limits per network prefix, a first-day limit for new lockers, public and reserved budget slices with alerts | someone with many networks can use up the public slices for a day; the reserved slices keep the guided demo working |
| Someone hosting abuse | upload and share | small and short-lived anonymous files, one open by default, proof of work, rate limits, downloads only, a warning before programs, no listing or search, noindex, the report form, removal by id | we can't scan encrypted content, by design |
| Script injection or a poisoned dependency | run code in our origin | no third-party code; a strict content security policy with Trusted Types where supported; no HTML sinks in our code; the one vendored artifact is pinned by hash; SRI on each page's top-level scripts and stylesheets, and the hash manifest for the modules they import | browser extensions (out of scope) |
| Draining our wallet through the API | spend the sponsor wallet | the internet-facing API runs as a separate user that can't reach the wallet; jobs are validated; daily budget slices; a firewall rule per user on the wallet port | at most the daily budgets |
Where Tari comes in
The Ootle is Tari's layer for applications, where payments are private by default and can carry sealed messages. We use it to deliver keys and move money, and every use below is something you can check.
Hidden on the chain
- Stealth outputs
- Sending a file to a Tari address, dead-drop deliveries, and paying for more room.
- Check:
/verify/tx/<id>shows the amount hidden, the owner a one-time key, the memo encrypted and the fee public. - Encrypted memos (XChaCha20-Poly1305)
- The file's key rides to one address inside the payment.
- Check: only the receiving locker opens it; any other key fails to decrypt.
- View keys, separate from spending
- Your inbox scans the chain in your browser;
/watchshows what a view key sees. - Check: for files sent to a locker, the view-key screen lists arrivals and opens no file. Files sent to another wallet open with its view key. More in who sees what.
- Private transactions built in your browser
- Sends signed and paid by your browser.
- Check: the transaction's input is your browser wallet's output, not ours.
Checked on the chain
- Payments
- Packs of more room, paid in tTARI to our receiving address with the invoice's reference inside it; the reference travels in the encrypted memo, so nothing on chain shows which invoice was paid, or by whom.
- Check: the official Tari library opens the commitment to the exact amount, then a Tari-run public indexer shows it committed.Check: our wallet sees it and a Tari-run public indexer confirms it exists on the chain. The amount is what our wallet reads.
- SealLog, a template of our own
- Public hashes of stored files and of every exit, on the Ootle.
- Check:
/verifychecks an inclusion proof against the root on chain.
Keys, not accounts
- Your locker
- No email, no password: a key that lives in your browser, and its Tari address.
- We store a random id and a hash of your login key. No email and no public key; a dead drop stores its own address, by design.
Why not an escrow template? On the Ootle, TARI held by a template reveals its amount. Native stealth outputs keep it hidden, so that's what we use.
How payments are checked
In September a wallet bug on the testnet showed deposits that never happened (forum thread). A wallet saying “sent” isn't enough, so we credit rented space only after our own checks.
We credit a payment only after the official Tari library opens its commitment to the exact amount and a Tari-run public indexer shows it committed on the chain. The check runs in a separate process that can only read; walletd never decides a credit.
We credit a payment only after our wallet sees it and a Tari-run public indexer confirms it exists on the chain. The amount is the one our wallet reads; this deployment doesn't prove it with the official Tari library.
The goodbye record
Every exit goes on the public record: we add it to SealLog on the Ootle at the next checkpoint (within ). It proves we said we deleted it, publicly and permanently. It can't prove we kept no copy.
Every stored file's ciphertext hash goes into SealLog on the Ootle. Your browser can check that your file is in it, unaltered. It proves what we held and when, not what we did with it later.
This deployment keeps no public record yet: SealLog is off here.
SealLog is a template on the Ootle. At each checkpoint, at most apart, we add one Merkle root over the ciphertext hash of every file we stored and a record of every exit. The log in use is the one /api/v1/config names.
- What a proof shows: that the tree we committed to at that epoch contains your file's ciphertext hash, or the record of its exit. Not that we held the bytes, and not that we deleted them.
- What nobody can change: the log has no owner, so nobody, us included, can change its rules or the code behind it. Anyone can check
owner_rule: "None"in its header on an indexer. Checkpoints are only ever added. - Who writes it: one key, our
servicekey, the same one that holds our public tTARI. It can add any root, stop, or start a new log. Nothing yet proves that each checkpoint extends the last one. - What it shows everyone: a rough upper bound on how many records (stored files plus exits) we've written, in steps of 64; for each checkpoint window, how many whole multiples of 64 records arrived (usually none); and the writer key.
- The code it runs: anyone can check that the template on the chain is our published
seal_log.wasm, byte for byte, withtemplate/check.sh --onchainand the template's address.
Check us
SRI only pins files to this page; it can't protect you from us. What can: comparing what we serve with the published source, release hashes notarized on the Ootle, and running your own copy.
- Every build writes a manifest with the SHA-256 of every file this site serves and the git commit it came from.
tools/verify-deploy.pyrebuilds the site from a clean checkout of that commit, downloads every file in the live manifest, and prints any difference.- Since SealLog went on, each release's manifest hash is also notarized through it; /releases.json lists them with their transactions. Anyone can notarize, so only events whose signer is the log's writer key are ours.
$ git clone https://github.com/c7b/mutis $ cd mutis $ python3 tools/verify-deploy.py https://srv2052606.hstgr.cloud 27e29462b1a6922aa3fcc4fa629793fdf4f07f87
It needs git and Python 3.11 or newer. This checks the site now. A browser can't pin it for you between visits.
Check it in your devtools
No analytics, no trackers, no third-party scripts or fonts. Your browser contacts a Tari-run indexer only when you press “Check it on Tari's indexer”. To see it for yourself:
- Open your browser's developer tools and choose the Network tab.
- Reload this page, then drop a file on the home page.
- Every request goes to this site's own address. Nothing else appears unless you press “Check it on Tari's indexer”.
Headers and content security policy
Every response carries HSTS, X-Content-Type-Options: nosniff, Referrer-Policy: no-referrer, Cross-Origin-Opener-Policy and Cross-Origin-Resource-Policy: same-origin, X-Frame-Options: DENY and a Permissions-Policy that turns off the camera, microphone, location, payment and USB APIs.
Pages allow scripts, styles, fonts and requests only from this origin, and nothing inline is allowed to run. The app pages add WebAssembly for the official Tari library, Trusted Types where the browser supports them, and the two Tari-run indexers for the “Check it on Tari's indexer” button.
Try to read one of our files
(Our hourly test file is between takes. Check back in a few minutes.)
Every hour we lock a test file. Here it is, exactly as our disk holds it.
Here's a file we locked . It's on our disk right now.
Download the stored bytescurl -OJ https://srv2052606.hstgr.cloud/api/v1/canary/rawIts key left on the Ootle, sealed to our own test locker: tx .
It shows what our disk holds. It can't prove we can't read your files: we locked this one ourselves, and we publish its key a day later.
Yesterday's key: now you can read it.
Once a test file is a day old, we publish its key. Your browser fetches the stored bytes and opens them here, the same way a link does.
Key:
Live evidence
Our own test transactions, never a user's. They come from /evidence.json, refreshed every hour; older ones are archived in the repository
- Network
- Official Tari library
- ootle-wasm , SHA-256
- Test deliveries (a file key sealed to our own test locker)
- Test payments (our demo wallet paying our own invoice)
Report a vulnerability
Please tell us privately before you tell anyone else. We'll answer, fix what's real, and credit you if you want.
- Leave us a file through our own dead drop
- Open a private security advisory on GitHub
- Report a link that hosts something harmful
The full threat model, with the findings of our own review, is in docs/threat-model.md.
What we can't protect you from
Beyond what our server sees (who sees what):
- The person you send it to. They can save, screenshot or forward it.
- Anyone who gets the full link. The link is the key. Use Link + password (sent separately) or send it to one Tari address.
- Chat apps that preview links. Their servers see the full link. They can't use up a view (opening takes a click), but they could open it.
- Your own browser. Your browser history, and any history sync, can keep the full link, key included. We clear the key from the address bar once it's opened, but we can't reach your history. Extensions allowed to read your tabs can see the link. Clipboard history (and cloud clipboards) can keep a copied link.
- A compromised device or extension. Encryption in the browser can't beat malware in the browser.
- A malicious version of this website. It's the known weak spot of all web encryption: if our server were compromised, it could serve code that leaks keys. SRI only pins files to this page; it can't protect you from us. What can: our verify-deploy script and running your own copy.
- Metadata. We see a padded size (rounded up so the exact size stays hidden: at least 1 KB, and at most 12% over for anything bigger), the hour it arrived, when it leaves (rounded up to the hour when that's an hour or more away; “midnight” is your own local midnight, which shows your time zone), its exit rule and how often it's opened. Not the name, the type, the contents or the key. Our server sees your IP address while you're connected. We don't write it to disk: rate limits use a keyed hash, kept in memory, with a key that changes every day. A VPN or Tor hides your IP from us; links without a locker work in Tor Browser's Safer mode, and Tari features need WebAssembly.
- On-chain facts. The chain shows an output with a hidden amount, a hidden owner and an encrypted memo. The fee is public. Payments our relay sends all come from one wallet with the same fee, so someone watching could group them as “sent by bye”, but not see to whom. Sends from your browser spend a grant from our sponsor wallet, then each send's change, so anyone reading the Ootle can link them to each other and to our sponsor wallet, but not see to whom or how much. SealLog shows roughly how many records (stored files plus exits) we write, in steps of 64, and when.
- Deletion you can't see. We delete on cue, and nothing can prove we kept no copy. Snapshots and free disk blocks are described above.
- Testnet resets. Esmeralda can be reset. Payments and on-chain records from before a reset are archived in our repository; files on our server are not affected.
- Legal requests. If compelled, we can hand over what we have: ciphertext, the columns on the “What we know” page, invoices. Not contents. Not keys.
What never touches a disk
Our server and web server never write your IP address, your links or your files' ids to a log. The database holds file and link ids, never keys; Privacy lists every table.
- Web server: no access log, and the error log drops addresses, paths, hosts and headers.
- API: logs only the route's name, the status and how long it took.
- Rate limits: a keyed hash of your network prefix, kept in memory, with a key that changes every day.
- Background jobs: fixed codes, never addresses, ids or memos. Our own test transactions are the only ones we publish.
- The firewall: logging is off. System journal: kept for seven days.
That's not the same as “nobody ever sees your IP”: our server sees it while you're connected, and so could our host.
Limits and space
Free
Today: per locker · of free
How we decide: every hour we take the disk, set aside what the system needs, what people have rented and a share for uploads without a locker, and divide the rest among lockers used in the last . We overbook like an airline (×): most people use a fraction of their share. The number moves slowly, never below or above .
If the disk ever truly fills, new uploads pause for everyone, and nothing already stored is lost.
When the number goes down, nothing of yours is deleted. You can't add more until you're under it again.
Files without a locker have their own reserved space, and small files (up to ) have a reserved lane of their own, so a busy day of big uploads can't crowd out a quick note.
Limits
| No locker | Free locker | Rented space | |
|---|---|---|---|
| Largest file | |||
| Opens per link | 1 to | 1 to | 1 to |
| Longest life of a link | |||
| Kept files (only you) | no | until you delete them | until you delete them |
| Text secrets | characters | characters | characters |
| Sends to a Tari address | a free locker opens for you | a day | a day |
A locker's first day is smaller, so a burst of new lockers can't take the disk (and new uploads pause before it fills): files up to , in total, links up to , sends to a Tari address. From its second active day, the free share applies.
Files left in a dead drop can be up to and open up to times within .
More room, rented in tTARI
| Pack | Price (testnet) | |
|---|---|---|
| + for | tTARI | Pay in tTARI, or try it with demo tTARI from the testnet grant your browser's wallet gets. |
| + for | tTARI | The same, for people who keep more. |
| Sold out | none | The disk is finite. We'd rather say no than overbook rented space. Free space still works. |
When rented space ends
Your limit goes back to the free share. Nothing is deleted for . After that, if you're still over, your oldest kept files are removed until you fit.
Unused lockers
Files kept by a locker that hasn't signed in for are deleted.
How paying works
We credit a payment only after the official Tari library opens its commitment to the exact amount and a Tari-run public indexer shows it committed on the chain.We credit a payment only after our wallet sees it and a Tari-run public indexer confirms it exists on the chain. The amount is the one our wallet reads. You pay our receiving address with this invoice's reference inside it; the reference travels in the payment's encrypted memo, so the chain doesn't show which invoice was paid, or by whom. The network fee is public on the chain. The amount and who paid are not. For space you rent from us we see the amount, because we're the seller. Nobody else does.
Sending a file to a Tari address
tTARI plus a network fee of per send, on us during the testnet.
Demo tTARITestnet tTARI for your browser
Try paid features with demo tTARI from our sponsor wallet, payments a day. Our demo wallet pays our own invoice: a real stealth transaction with play money. You can check it on the chain.When your locker opens, our sponsor wallet sends its browser wallet a grant of tTARI, and again on a later day when the wallet runs short: one grant a day per locker, and two a day per network. Packs are paid from it: a real stealth transaction with play money, built and signed in your browser. You can check it on the chain.
Testnet. tTARI has no monetary value. These prices are real logic with play money.
Ootle mainnet launches . Paid features stay on the testnet until our code has been reviewed.
How it was built
Built with AI coding agents under the author's direction. The design, threat model and crypto choices were reviewed by the author. Python's standard library on the server, plain JavaScript in the browser. One runtime dependency: Tari's official ootle-wasm , pinned by its sha512.
Every release runs the server, site, browser and end-to-end test suites first; the records are in the repository. This deployment runs commit 27e29462b1a6922aa3fcc4fa629793fdf4f07f87.
Run your own
File sharing needs Python's standard library and a web server. The Tari features also need a walletd on the Ootle testnet and Node for the payment checker. Self-host guide
Who's behind it
bye is built by an independent developer in Mexico, for the Tari community's October 2026 “Spooky Secrets” build contest, and it's meant to outlive it. The name says what it does: your friend sees the secret, and then it says bye.
The fine print (privacy, terms and how to report a link) is on one page: the fine print.