diff --git a/cdn/plugins.json b/cdn/plugins.json index 5f280c2..91bfd7f 100644 --- a/cdn/plugins.json +++ b/cdn/plugins.json @@ -59,6 +59,10 @@ "identifier": "dev.randombits.excalidraw", "staticFiles": ["dist", "package.json"] }, + { + "identifier": "io.github.nickstruglia.keyfold", + "staticFiles": ["dist", "package.json"] + }, { "identifier": "com.sncommunity.standard-blue-theme", "staticFiles": ["dist", "package.json"] diff --git a/packages/io.github.nickstruglia.keyfold/LICENSE b/packages/io.github.nickstruglia.keyfold/LICENSE new file mode 100644 index 0000000..436026c --- /dev/null +++ b/packages/io.github.nickstruglia.keyfold/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Nicholas Truglia + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/io.github.nickstruglia.keyfold/README.md b/packages/io.github.nickstruglia.keyfold/README.md new file mode 100644 index 0000000..04768df --- /dev/null +++ b/packages/io.github.nickstruglia.keyfold/README.md @@ -0,0 +1,36 @@ +# Keyfold + +A key manager for Standard Notes: crypto seed phrases and wallet keys, plus SSH and PGP keys, API tokens and recovery +codes. Each entry folds into a one-line card, secrets stay hidden until revealed, saved entries open locked against +accidental changes, seed phrases and keys are checked for typos (BIP39, Electrum, Monero and aezeed checksums, +Base58Check, Bech32, PGP armor), and an optional vault password encrypts the whole note again (AES-256-GCM, +PBKDF2-SHA256 with 600,000 iterations). Encrypted backup files open in a single-file offline viewer, without Standard +Notes, and restore into an empty Keyfold note. + +Its Content Security Policy blocks every outgoing connection (`connect-src 'none'`), and scripts, images and fonts +from other sites. The only runtime dependency is Preact. + +- Source, tests and documentation: https://github.com/nickstruglia/standard-notes-keyfold (MIT) +- This copy: version 1.0.31, built from commit [`77e7bd8`](https://github.com/nickstruglia/standard-notes-keyfold/commit/77e7bd8bac96194cc162e63c118a7ac24687e712) + +## Why the files are prebuilt + +This repository builds its packages on Node 16, and Keyfold's build (Vite 8) needs Node 20.19 or newer. So +`prebuilt/` holds the output of Keyfold's own build for this package's address, and `yarn build` checks every file +against `SHA256SUMS` before copying it to `dist/`. + +## Rebuilding and comparing + +With Node 22.12 or newer: + +```sh +git clone https://github.com/nickstruglia/standard-notes-keyfold.git +cd standard-notes-keyfold +git checkout 77e7bd8bac96194cc162e63c118a7ac24687e712 +npm ci --ignore-scripts +node scripts/directory-package.mjs 1.0.31 +diff -r directory-package/io.github.nickstruglia.keyfold/prebuilt /prebuilt +diff directory-package/io.github.nickstruglia.keyfold/SHA256SUMS /SHA256SUMS +``` + +The script builds Keyfold for `https://standardnotes.github.io/plugins/cdn/dist/static/io.github.nickstruglia.keyfold/dist/` and writes this folder, with the same files byte for byte. diff --git a/packages/io.github.nickstruglia.keyfold/SHA256SUMS b/packages/io.github.nickstruglia.keyfold/SHA256SUMS new file mode 100644 index 0000000..fdc4da6 --- /dev/null +++ b/packages/io.github.nickstruglia.keyfold/SHA256SUMS @@ -0,0 +1,4 @@ +68c5e8303d6404139810f4922454a4b63147d7df30523db485de62aa30656417 assets/index-5lEe8QFz.js +0e0ccb766d5e6a479278c3c98865189e0f0bde69ae739d75a1d26470613de64c icon.svg +b3e4d9d442990d877b3a95de634c3c70c74e4fd93c0f0902ec77822dc5a13deb index.html +7a444a29f7d33c083f56424000729be5572e7b91db735bc67f2153fff7e4ea9c keyfold-viewer.html diff --git a/packages/io.github.nickstruglia.keyfold/build.mjs b/packages/io.github.nickstruglia.keyfold/build.mjs new file mode 100644 index 0000000..1faebd2 --- /dev/null +++ b/packages/io.github.nickstruglia.keyfold/build.mjs @@ -0,0 +1,37 @@ +// Copies the prebuilt files to dist/ after checking each one against SHA256SUMS. +// They are Keyfold's own build for this address; README.md says how to rebuild them. +import { createHash } from 'crypto' +import { copyFileSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync } from 'fs' +import { dirname, join, relative } from 'path' +import { fileURLToPath } from 'url' + +const here = dirname(fileURLToPath(import.meta.url)) +const prebuilt = join(here, 'prebuilt') +const dist = join(here, 'dist') + +const walk = (dir) => + readdirSync(dir).flatMap((name) => { + const path = join(dir, name) + return statSync(path).isDirectory() ? walk(path) : [relative(prebuilt, path).split('\\').join('/')] + }) + +const sums = new Map( + readFileSync(join(here, 'SHA256SUMS'), 'utf8') + .trim() + .split('\n') + .map((line) => { + const [hash, file] = line.split(' ') + return [file, hash] + }), +) +const files = walk(prebuilt).sort() +if (files.join('\n') !== [...sums.keys()].sort().join('\n')) throw new Error('prebuilt/ does not match SHA256SUMS') + +rmSync(dist, { recursive: true, force: true }) +for (const file of files) { + const hash = createHash('sha256').update(readFileSync(join(prebuilt, file))).digest('hex') + if (hash !== sums.get(file)) throw new Error(`${file} does not match SHA256SUMS`) + mkdirSync(dirname(join(dist, file)), { recursive: true }) + copyFileSync(join(prebuilt, file), join(dist, file)) +} +console.log(`Keyfold: ${files.length} files checked and copied to dist/`) diff --git a/packages/io.github.nickstruglia.keyfold/package.json b/packages/io.github.nickstruglia.keyfold/package.json new file mode 100644 index 0000000..a7dac28 --- /dev/null +++ b/packages/io.github.nickstruglia.keyfold/package.json @@ -0,0 +1,28 @@ +{ + "name": "sn-keyfold", + "version": "1.0.31", + "private": true, + "description": "A key manager for Standard Notes: seed phrases, wallet, SSH and PGP keys, API tokens and recovery codes, in collapsible cards with hidden fields and checksum checks.", + "author": "Nicholas Truglia", + "license": "MIT", + "homepage": "https://github.com/nickstruglia/standard-notes-keyfold", + "repository": { + "type": "git", + "url": "https://github.com/standardnotes/plugins", + "directory": "packages/io.github.nickstruglia.keyfold" + }, + "scripts": { + "build": "node build.mjs" + }, + "sn": { + "name": "Keyfold", + "content_type": "SN|Component", + "area": "editor-editor", + "main": "dist/index.html", + "file_type": "json", + "interchangeable": false, + "marketing_url": "https://github.com/nickstruglia/standard-notes-keyfold", + "thumbnail_url": "https://standardnotes.github.io/plugins/cdn/dist/static/io.github.nickstruglia.keyfold/dist/icon.svg", + "showInGallery": true + } +} diff --git a/packages/io.github.nickstruglia.keyfold/prebuilt/assets/index-5lEe8QFz.js b/packages/io.github.nickstruglia.keyfold/prebuilt/assets/index-5lEe8QFz.js new file mode 100644 index 0000000..d1969b0 --- /dev/null +++ b/packages/io.github.nickstruglia.keyfold/prebuilt/assets/index-5lEe8QFz.js @@ -0,0 +1,495 @@ +(function(){var e=document.createElement(`style`);e.textContent=`:root{--bg:var(--sn-stylekit-background-color,#fff);--fg:var(--sn-stylekit-foreground-color,#1d1d20);--muted:var(--sn-stylekit-passive-color-0,var(--sn-stylekit-neutral-color,#6c7079));--border:var(--sn-stylekit-border-color,#e0e2e6);--panel:var(--sn-stylekit-secondary-background-color,#f6f7f9);--contrast:var(--sn-stylekit-contrast-background-color,#eef0f3);--info:var(--sn-stylekit-info-color,#086dd6);--info-fg:var(--sn-stylekit-info-contrast-color,#fff);--success:var(--sn-stylekit-success-color,#1e8a34);--warning:var(--sn-stylekit-warning-color,#a96500);--danger:var(--sn-stylekit-danger-color,#cc1f36);--danger-fg:var(--sn-stylekit-danger-contrast-color,#fff);--placeholder:var(--sn-stylekit-input-placeholder-color,var(--muted));--success-text:color-mix(in srgb, var(--success) 70%, var(--fg));--warning-text:color-mix(in srgb, var(--warning) 55%, var(--fg));--danger-text:color-mix(in srgb, var(--danger) 75%, var(--fg));--keys:color-mix(in srgb, var(--info) 60%, var(--danger));--font:var(--sn-stylekit-sans-serif-font,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);--mono:var(--sn-stylekit-monospace-font,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);--radius:6px;--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark}@media (prefers-color-scheme:dark){:root{--lightningcss-light: ;--lightningcss-dark:initial}html.standalone{--bg:#17181b;--fg:#e7e8ea;--muted:#9a9ea6;--border:#2e3036;--panel:#1d1f23;--contrast:#262930;--info:#4c9df0;--success:#4fbf63;--warning:#e3a33a;--danger:#f0566a;--placeholder:#6d7179}}html.theme-pending{opacity:0}*{box-sizing:border-box}html,body{background:var(--bg);height:100%;color:var(--fg);font:14px/1.45 var(--font);margin:0}#app,.app{flex-direction:column;height:100%;min-height:0;display:flex}h2,h3{margin:0;font-weight:600}h2{font-size:1.15rem}h3{align-items:center;gap:6px;font-size:.95rem;display:flex}a{color:var(--info)}code{font-family:var(--mono);word-break:break-all;font-size:.9em}.muted{color:var(--muted)}.small{font-size:.85rem}.input{width:100%;min-width:0;font:inherit;color:var(--fg);background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);outline:none;padding:7px 9px}.input::placeholder{color:var(--placeholder)}.input:focus-visible,.button:focus-visible,.icon-button:focus-visible,.entry-item:focus-visible{outline:2px solid var(--info);outline-offset:1px}.input[readonly]{background:var(--panel)}textarea.input{resize:vertical;min-height:2.6em}select.input{width:auto;padding-right:4px}.mono{font-family:var(--mono)}.masked-placeholder{text-align:left;cursor:pointer;color:var(--muted);letter-spacing:2px}.button{font:inherit;color:var(--fg);background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);cursor:pointer;white-space:nowrap;align-items:center;gap:6px;padding:7px 12px;font-weight:500;display:inline-flex}.button.small{padding:4px 9px;font-size:.85rem}.button.primary{background:var(--info);border-color:var(--info);color:var(--info-fg)}.button.danger{color:var(--danger);border-color:var(--danger)}.button:disabled,.icon-button:disabled{opacity:.5;cursor:not-allowed}.icon-button{width:30px;height:30px;color:var(--muted);border-radius:var(--radius);cursor:pointer;background:0 0;border:1px solid #0000;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.icon-button.active{color:var(--warning)}.check{cursor:pointer;align-items:flex-start;gap:8px;margin:6px 0;display:flex}.check input{margin-top:3px}.row{flex-wrap:wrap;align-items:flex-end;gap:10px;display:flex}.row>.field{flex:180px}.row.tight{gap:6px}.row.end{justify-content:flex-end}.grow{flex:200px}.field{flex-direction:column;gap:4px;min-width:0;margin-bottom:10px;display:flex}.field-control{display:contents}.field-label{color:var(--muted);font-size:.8rem;font-weight:600}.hint{color:var(--muted);margin:0;font-size:.8rem}.status{align-items:baseline;gap:6px;margin:6px 0 10px;font-size:.85rem;display:flex}.status svg{flex:none;align-self:flex-start;margin-top:.2em}.status-ok{color:var(--success-text)}.status-error{color:var(--danger-text)}.status-warn{color:var(--warning-text)}.status-info{color:var(--muted)}.pill{white-space:nowrap;background:var(--contrast);color:var(--muted);border-radius:999px;align-items:center;gap:3px;padding:0 7px;font-size:.72rem;line-height:1.6;display:inline-flex}.pill-ok{color:var(--success-text);background:color-mix(in srgb, var(--success) 13%, transparent)}.pill-error{color:var(--danger-text);background:color-mix(in srgb, var(--danger) 13%, transparent)}.pill-warn{color:color-mix(in srgb, var(--warning) 45%, var(--fg));background:color-mix(in srgb, var(--warning) 15%, transparent)}.badge{border-radius:999px;flex:none;padding:2px 8px;font-size:.75rem;font-weight:600}.badge-mnemonic{color:var(--info);background:color-mix(in srgb, var(--info) 12%, transparent)}.badge-privateKey{color:var(--success);background:color-mix(in srgb, var(--success) 12%, transparent)}.badge-other,.badge-recoveryCodes{color:var(--muted);background:var(--contrast)}.badge-sshKey,.badge-pgpKey,.badge-apiKey,.badge-genericKey{color:var(--keys);background:color-mix(in srgb, var(--keys) 12%, transparent)}.banner{background:var(--contrast);border-bottom:1px solid var(--border);padding:8px 14px;font-size:.85rem}.banner svg{vertical-align:-3px;margin-right:4px}.banner-warn{color:var(--fg);background:color-mix(in srgb, var(--warning) 16%, var(--bg))}.layout{flex:1;grid-template-columns:minmax(260px,340px) minmax(0,1fr);min-height:0;display:grid}.sidebar{border-right:1px solid var(--border);background:var(--panel);flex-direction:column;min-height:0;display:flex}.toolbar{background:var(--panel);border-bottom:1px solid var(--border);flex-direction:column;gap:8px;padding:10px 12px;display:flex}.toolbar-row{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.spacer{flex:1}.search{color:var(--muted);flex:200px;position:relative}.search svg{position:absolute;top:50%;left:9px;transform:translateY(-50%)}.search .input{padding-left:30px}.popover-wrap{position:relative}.popover{z-index:15;background:var(--bg);border:1px solid var(--border);border-radius:8px;min-width:190px;max-height:70vh;padding:6px;position:absolute;top:calc(100% + 4px);right:0;overflow-y:auto;box-shadow:0 8px 24px #00000029}.popover-dialog{width:270px;padding:12px}.menu-heading{letter-spacing:.04em;text-transform:uppercase;color:var(--muted);padding:6px 10px 2px;font-size:.72rem;font-weight:600}.menu-group+.menu-group{border-top:1px solid var(--border);margin-top:4px;padding-top:4px}.menu-item{width:100%;font:inherit;text-align:left;color:var(--fg);border-radius:var(--radius);cursor:pointer;background:0 0;border:0;align-items:center;gap:8px;padding:7px 10px;display:flex}.menu-item:focus-visible{background:var(--contrast)}.view-options fieldset{border:0;margin:0 0 10px;padding:0}.view-options legend{color:var(--muted);margin-bottom:2px;padding:0;font-size:.8rem;font-weight:600}.view-options .check{margin:3px 0}.view-options select.input{width:100%}.group-heading{text-transform:uppercase;letter-spacing:.04em;margin:10px 0 4px;font-size:.78rem}.group:first-child .group-heading{margin-top:0}.group-toggle{width:100%;font:inherit;color:var(--muted);border-radius:var(--radius);cursor:pointer;text-transform:inherit;letter-spacing:inherit;background:0 0;border:0;align-items:center;gap:6px;padding:4px;font-weight:600;display:flex}.count{background:var(--contrast);border-radius:999px;padding:0 6px;font-size:.72rem}.toolbar .count{background:0 0;padding:0;font-size:.8rem}.chevron{flex:none;transition:transform .15s}[aria-expanded=true]>.chevron{transform:rotate(90deg)}.entry-list{flex:1;padding:8px 6px;overflow-y:auto}.entry-rows{margin:0;padding:0;list-style:none}.entry-item{width:100%;font:inherit;text-align:left;color:var(--fg);border-radius:var(--radius);cursor:pointer;background:0 0;border:1px solid #0000;align-items:flex-start;gap:10px;padding:9px 10px;display:flex}.entry-item.selected{background:color-mix(in srgb, var(--info) 10%, var(--bg));border-color:var(--border);box-shadow:inset 3px 0 0 var(--info)}.entry-icon{border-radius:var(--radius);padding:6px;display:inline-flex}.entry-main{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.entry-title{text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.entry-title .star{color:var(--warning);vertical-align:-1px;margin-right:4px}.entry-meta{color:var(--muted);text-overflow:ellipsis;white-space:nowrap;font-size:.8rem;overflow:hidden}.entry-pills{flex-wrap:wrap;gap:4px;display:flex}.entry-pills:empty{display:none}.entry-date{color:var(--muted);flex:none;font-size:.75rem}.empty{text-align:center;color:var(--muted);padding:24px 16px}.empty p{margin:6px 0}.detail{min-width:0;min-height:0;overflow-y:auto}.detail.full{flex:1}.stack{max-width:980px;margin:0 auto;padding:12px 12px 48px}.cards{flex-direction:column;gap:6px;margin:0;padding:0;list-style:none;display:flex}.card-entry{background:var(--bg);border:1px solid var(--border);border-radius:8px}.card-entry.open{box-shadow:0 2px 10px #00000012}.card-header{border-radius:8px;align-items:center;gap:4px;padding-right:6px;display:flex}.card-entry.open .card-header{z-index:3;background:var(--bg);border-bottom:1px solid var(--border);border-radius:8px 8px 0 0;position:sticky;top:0}.card-toggle{min-width:0;font:inherit;text-align:left;color:var(--fg);cursor:pointer;background:0 0;border:0;border-radius:8px;flex:auto;align-items:flex-start;gap:10px;padding:10px 12px;display:flex}.card-toggle>.chevron{color:var(--muted);margin-top:7px}.card-toggle:focus-visible,.group-toggle:focus-visible,.section-toggle:focus-visible{outline:2px solid var(--info);outline-offset:-2px}.card-body{padding:0 16px 12px 46px}.entry-actions{flex:none;display:flex}.empty .row.center{justify-content:center;margin-top:12px}.kind-choices{grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:6px;max-width:640px;margin:8px auto 10px;display:grid}.kind-choices .button{white-space:normal;text-align:left;justify-content:flex-start}.kind-choices svg{flex:none}.placeholder{flex-direction:column;justify-content:center;align-items:center;gap:8px;height:100%;display:flex}.editor-header{z-index:2;background:var(--bg);border-bottom:1px solid var(--border);align-items:center;gap:6px;padding:10px 16px;display:flex;position:sticky;top:0}.title-input{border-color:#0000;flex:1;font-size:1.1rem;font-weight:600}.title-input:focus{border-color:var(--border)}.editor-body{max-width:880px;padding:8px 16px 32px}.editor-footer{margin-top:16px}.back-button{display:none}.section{border-bottom:1px solid var(--border);padding:10px 0 6px}.section:last-of-type{border-bottom:none}.section.closed{padding-bottom:10px}.section-header{justify-content:space-between;align-items:center;gap:8px;margin-bottom:10px;display:flex}.section.closed .section-header{margin-bottom:0}.section-heading{flex:1;min-width:0}.section-toggle{width:100%;font:inherit;text-align:left;color:var(--fg);border-radius:var(--radius);cursor:pointer;background:0 0;border:0;align-items:center;gap:6px;padding:2px 4px;font-weight:600;display:flex}.section-toggle>.chevron{color:var(--muted)}.section-summary{min-width:0;color:var(--muted);text-overflow:ellipsis;white-space:nowrap;margin-left:4px;font-size:.82rem;font-weight:400;overflow:hidden}.section>h3{margin-bottom:10px}.section p{margin:0 0 10px}.secret{align-items:center;gap:2px;display:flex}.secret-multiline{align-items:flex-start}.secret-actions{flex:none;display:flex}.secret-multiline .secret-actions{flex-direction:column}.word-toolbar{flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:8px;display:flex}.word-grid{grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:6px;margin:0 0 6px;padding:0;list-style:none;display:grid}.word{position:relative}.word-index{min-width:18px;color:var(--muted);text-align:right;pointer-events:none;font-size:.75rem;position:absolute;top:50%;left:8px;transform:translateY(-50%)}.word .input{padding-left:30px;padding-right:6px}.word .input::-webkit-calendar-picker-indicator{display:none!important}.word .input::-webkit-list-button{display:none!important}.word-invalid .input{border-color:var(--danger);background:color-mix(in srgb, var(--danger) 6%, var(--bg))}.custom-field{grid-template-columns:minmax(110px,.6fr) minmax(0,1.4fr) auto;align-items:center;gap:8px;margin-bottom:8px;display:grid}.custom-actions{align-items:center;gap:4px;display:flex}.custom-actions .check{margin:0}.backup-row{align-items:center;margin-bottom:8px}.backup-row input[type=date]{width:auto}.screen{flex:1;justify-content:center;align-items:center;padding:24px 16px;display:flex;overflow:auto}.card{text-align:center;background:var(--bg);border:1px solid var(--border);border-radius:10px;flex-direction:column;align-items:center;gap:10px;width:100%;max-width:420px;padding:24px;display:flex}.card p{margin:0}.lock-card .input,.lock-card .button{justify-content:center;width:100%}.open-note,.restore-backup{width:100%;max-width:640px}.open-note textarea,.restore-backup textarea{width:100%}.screen.dragging .open-note,.screen.dragging .restore-backup{border-color:var(--info);box-shadow:0 0 0 3px color-mix(in srgb, var(--info) 30%, transparent)}.paste-note{width:100%}.lock-bar{color:var(--muted);background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);align-items:center;gap:8px;margin:10px 0 4px;padding:4px 4px 4px 10px;font-size:.85rem;display:flex}.lock-bar>span{flex:1;min-width:0}.lock-bar>svg{flex:none}.lock-bar.editing{color:var(--fg);border-color:var(--info)}.notices>summary{color:var(--info);cursor:pointer}.notices pre{white-space:pre-wrap;overflow-wrap:anywhere;color:var(--muted)}.paste-note>summary{color:var(--info);cursor:pointer;font-size:.85rem}.paste-note>*+*{margin-top:10px}a.button{text-decoration:none}.backup-ready>.row{margin-bottom:10px}.password-form{max-width:460px}.overlay{z-index:40;background:#00000059;justify-content:center;align-items:center;padding:16px;display:flex;position:fixed;inset:0}.dialog{text-align:left;align-items:stretch;box-shadow:0 10px 30px #0003}.toasts{z-index:30;pointer-events:none;flex-direction:column;align-items:flex-end;gap:8px;display:flex;position:fixed;bottom:16px;left:16px;right:16px}.toast{background:var(--bg);border:1px solid var(--border);border-left:4px solid var(--info);border-radius:var(--radius);pointer-events:auto;align-items:center;gap:8px;max-width:420px;padding:8px 8px 8px 12px;font-size:.85rem;display:flex;box-shadow:0 4px 16px #00000026}.toast-success{border-left-color:var(--success)}.toast-error{border-left-color:var(--danger)}.app.privacy .layout,.app.privacy .toolbar,.app.privacy .detail{filter:blur(10px);pointer-events:none;-webkit-user-select:none;user-select:none}.app.privacy~.overlay,.app.privacy~.toasts{filter:blur(10px)}.privacy-cover{z-index:10;width:100%;font:inherit;cursor:pointer;color:var(--muted);background:0 0;border:0;flex-direction:column;justify-content:center;align-items:center;gap:8px;display:flex;position:fixed;inset:0}.app.compact{font-size:13px}.app.compact .input{padding:4px 7px}.app.compact .button{padding:4px 9px}.app.compact .toolbar{gap:6px;padding:6px 10px}.app.compact .stack{padding-top:8px}.app.compact .cards{gap:4px}.app.compact .card-toggle,.app.compact .entry-item{align-items:center;padding:5px 10px}.app.compact .card-toggle>.chevron{margin-top:0}.app.compact .entry-icon{padding:3px}.app.compact .entry-main{flex-direction:row;align-items:center;gap:8px}.app.compact .entry-title{text-overflow:ellipsis;white-space:nowrap;flex:none;min-width:0;max-width:60%;overflow:hidden}.app.compact .entry-meta{flex:0 10 auto;min-width:0}.app.compact .entry-pills{flex-wrap:nowrap;flex:0 auto;min-width:0;overflow:hidden}.app.compact .sidebar .entry-date,.app.compact .entry-pills .pill:not(.pill-error):not(.pill-warn){display:none}.app.compact .card-body{padding:0 12px 8px 36px}.app.compact .section{padding:6px 0 4px}.app.compact .section.closed{padding-bottom:6px}.app.compact .section-header{margin-bottom:6px}.app.compact .section.closed .section-header{margin-bottom:0}.app.compact .field{margin-bottom:6px}.app.compact .helper,.app.compact .field>.hint:not([class*=status-]):not(.hint-safety){display:none}.app.compact .word-grid{grid-template-columns:repeat(auto-fill,minmax(112px,1fr));gap:4px}.app.compact .word .input{padding-left:28px}.app.compact .search .input{padding-left:30px}.app.compact .editor-footer{margin-top:8px}@media (pointer:coarse){.input,.app.compact .input{font-size:16px}.icon-button{width:40px;height:40px}.entry-actions{gap:6px}}@media (max-width:560px){.toolbar .button-text,.app.compact .entry-meta{display:none}.toolbar .button{padding:5px 8px}.toolbar .search{flex-basis:100%}.toolbar .filter{flex:1 1 0;min-width:0}.toolbar .add-button .button-text{display:inline}.toolbar .add-button{padding:5px 12px}.kind-choices{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width:760px){.card-header{flex-wrap:wrap}.card-entry.open .entry-actions{margin-left:auto}.card-body,.app.compact .card-body{padding:0 10px 10px}.entry-date{display:none}.layout{grid-template-columns:minmax(0,1fr)}.layout.has-detail .sidebar,.layout:not(.has-detail) .detail{display:none}.sidebar{border-right:none}.back-button{display:inline-flex}.editor-header{flex-wrap:wrap;padding:8px 10px}.editor-header .badge{margin-right:auto}.title-input{flex-basis:100%;order:10}.editor-body{padding:4px 12px 24px}.custom-field{grid-template-columns:minmax(0,1fr)}.word-grid{grid-template-columns:repeat(auto-fill,minmax(120px,1fr))}}@media (max-width:560px){.toolbar-row{position:relative}.popover-wrap{position:static}.popover{min-width:0;left:0;right:0}.popover-dialog{width:auto}}@media (max-width:760px),(max-height:560px){.card-entry.open .card-header{position:static}}@media (pointer:coarse){.button,.toolbar .button,.toolbar select.input{min-height:40px}.toolbar .button{min-width:36px}.group-toggle,.section-toggle{min-height:40px}.menu-item{min-height:44px}.check{align-items:center;min-height:40px}.check input{width:20px;height:20px}}@media (hover:hover){.button:hover:not(:disabled){background:var(--contrast)}.button.primary:hover:not(:disabled){background:var(--info);filter:brightness(1.08)}.button.danger:hover:not(:disabled){background:var(--danger);color:var(--danger-fg)}.icon-button:hover:not(:disabled){color:var(--fg);background:var(--contrast)}.icon-button.danger:hover:not(:disabled){color:var(--danger)}.group-toggle:hover{color:var(--fg)}.entry-item:hover{background:var(--contrast)}.card-toggle:hover{background:var(--panel)}.menu-item:hover{background:var(--contrast)}.title-input:hover{border-color:var(--border)}}.input::-webkit-date-and-time-value{text-align:start}@media (forced-colors:active){.pill,.status-error,.entry-item.selected,.word-invalid .input{border:1px solid canvastext}.entry-item.selected{border-color:highlight}.word-invalid .input{border-width:2px}}@supports not (color:color-mix(in srgb, red, red)){:root{--keys:var(--info);--success-text:var(--success);--warning-text:var(--fg);--danger-text:var(--danger)}.pill-ok,.pill-error,.pill-warn,.badge,[class*=badge-],.entry-item.selected,.word-invalid .input{background:var(--contrast)}.pill-warn{color:var(--fg)}}@media print{.app{display:none}}.link-button{font:inherit;color:var(--info);cursor:pointer;background:0 0;border:0;margin:0 .25em;padding:0;text-decoration:underline} +/*$vite$:1*/`,document.head.appendChild(e);var t,n,r,i,a,o,s,c,l,u,d,f,p,m={},h=[],g=/^m(i|n|o|s|text|space)$/,_=Array.isArray,v=h.slice,y=Object.assign;function b(e){e&&e.parentNode&&e.remove()}function x(e,t,n){var r,i,a,o={},s=arguments.length;for(a in t)a==`key`?r=t[a]:a==`ref`&&typeof e!=`function`?i=t[a]:o[a]=t[a];return s>2&&(o.children=s>3?v.call(arguments,2):n),S(e,o,r,i,null)}function S(e,r,i,a,o){var s={type:e,props:r,key:i,ref:a,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:o||++n,__i:-1,__u:0};return!o&&t.vnode&&t.vnode(s),s}function C(e){return e.children}function w(e,t){this.props=e,this.context=t,this.__g=0}function T(e,t){if(t==null)return e.__?T(e.__,e.__i+1):null;for(var n;tn&&r.sort(o),e=r.shift(),n=r.length,8&e.__g&&(s=void 0,c=void 0,l=(c=(i=e).__v).__e,u=[],d=[],(f=i.__P)&&((s=y({constructor:void 0},c)).__v=c.__v+1,t.vnode&&t.vnode(s),oe(f,s,c,i.__n,f.namespaceURI,32&c.__u?[l]:null,u,l||T(c),32&c.__u,d),s.__v=c.__v,s.__.__k[s.__i]=s,ce(u,s,d),c.__=c.__e=null,s.__e!=l&&E(s)))}finally{r.length=a=0}}function ee(e,t,n,r,i,a,o,s,c,l,u){var d,f,p,g,_,v,y=r.__k||h,b=t.length;for(c=te(n,t,y,c,b),d=0;dc?v--:v++,y=!0)):(~l||(i>h?v--:i>1]+!!u){for(i=n-1,a=n+1;i>=0||a=0?i--:a++])&&!(2&l.__u)&&s==l.key&&c==l.type)return o}return-1}function re(e,t,n){n??=``,t[0]==`-`?e.setProperty(t,n):e[t]=n}function ie(e,t,n,r,i){var a;n:if(t==`style`){if(typeof n==`string`)e.style.cssText=n;else{if(typeof r==`string`&&(e.style.cssText=r=``),r)for(t in r)n&&t in n||re(e.style,t,``);if(n)for(t in n)r&&n[t]==r[t]||re(e.style,t,n[t])}}else if(t[0]==`o`&&t[1]==`n`)a=t!=(t=t.replace(l,`$1`)),(t=t.slice(2))[0]<`a`&&(t=t.toLowerCase()),(e.__e||={})[t+a]=n,n?r?n[c]=r[c]:(n[c]=u,e.addEventListener(t,a?f:d,a)):e.removeEventListener(t,a?f:d,a);else{if(i==`http://www.w3.org/2000/svg`)t=t.replace(/xlink(H|:h)/,`h`).replace(/sName$/,`s`);else if(t!=`width`&&t!=`height`&&t!=`href`&&t!=`list`&&t!=`form`&&t!=`tabIndex`&&t!=`download`&&t!=`rowSpan`&&t!=`colSpan`&&t!=`role`&&t!=`popover`&&t in e)try{e[t]=n??``;break n}catch{}typeof n==`function`||(n==null||!1===n&&t[4]!=`-`?e.removeAttribute(t):e.setAttribute(t,t==`popover`&&n==1?``:n))}}function ae(e){return function(n){if(this.__e){var r=this.__e[n.type+e];if(n[s]==null)n[s]=u++;else if(n[s]=n.__.length&&n.__.push({}),n.__[e]}function z(e){return I=1,Se(Pe,e)}function Se(e,t,n){var r=xe(fe++,2);if(r.t=e,!r.__c&&(r.__=[n?n(t):Pe(void 0,t),function(e){var t=r.__N?r.__N[0]:r.__[0],n=r.t(t,e);F(t,n)||(r.__N=[n,r.__[1]],r.__c.setState({}))}],r.__c=N,!N.__f)){N.__f=!0;var i=N.shouldComponentUpdate;N.shouldComponentUpdate=function(e,t,n){var r=this.__H;if(!r)return!0;var a=!1,o=this.props!=e;if(r.__.some(function(e){e.__N&&(a=!0,F(e.__[0],e.__N[0])||(o=!0))}),i){var s=i.call(this,e,t,n);return a?s||o:s}return!a||o}}return r.__}function B(e,t){var n=xe(fe++,3);!L.__s&&Ne(n.__H,t)&&(n.__P=!0,n.__=e,n.u=t,N.__H.__h.push(n))}function V(e){return I=5,Ce(function(){return{current:e}},[])}function Ce(e,t){var n=xe(fe++,7);return Ne(n.__H,t)&&(n.__=e(),n.__H=t),n.__}function we(e,t){return I=8,Ce(function(){return e},t)}function Te(e){var t=N.context[e.__c],n=xe(fe++,9);return n.c=e,t?(n.__??(n.__=!0,t.sub(N)),t.props.value):e.__}function Ee(){var e=xe(fe++,11);if(!e.__){for(var t=N.__v;!t.__m&&t.__;)t=t.__;var n=t.__m||(t.__m=[0,0]);e.__=`P`+n[0]+`-`+n[1]++}return e.__}function De(){var e;do{for(;e=he.shift();)try{je(e)}catch(t){L.__e(t,{__:(e=e.__P)&&e.__v})}for(;e=me.shift();){var t=e.__H;if(e.__P&&t)try{t.__h.some(je),t.__h.some(Me),t.__h=[]}catch(n){t.__h=[],L.__e(n,e.__v)}}}while(he.length)}L.__b=function(e){N=null,ge&&ge(e)},L.__=function(e,t){e&&t.__k&&t.__k.__m&&(e.__m=t.__k.__m),R&&R(e,t)},L.__r=function(e){_e&&_e(e),fe=0;var t=(N=e.__c).__H;t&&(pe==N?N.__h=[]:(t.__h.some(je),t.__h.some(Me),fe=0),t.__h=[],t.__.some(function(e){e.__N&&(e.__=e.__N),e.u=e.__N=void 0})),pe=N},L.diffed=function(e){ve&&ve(e);var t=e.__c;t&&t.__H&&(t.__H.__h.length&&Ae(me.push(t)),t.__H.__.some(function(e){e.u&&(e.__H=e.u)})),pe=N=null},L.__c=function(e,t){t.some(function(e){try{e.__h.some(je),e.__h=e.__h.filter(function(e){return!e.__||Me(e)})}catch(n){t.some(function(e){e.__h&&=[]}),t=[],L.__e(n,e.__v)}}),ye&&ye(e,t)},L.unmount=function(e){be&&be(e);var t,n,r=e.__c;r&&r.__H&&(r.__H.__.some(function(r){try{if(r.__P&&r.__c){if(n===void 0){for(n=e.__;n&&(!n.__c||!n.__c.__P);)n=n.__;n&&=n.__c}r.__P=n,Ae(he.push(r))}else je(r)}catch(e){t=e}}),r.__H=void 0,t&&L.__e(t,r.__v))};var Oe=typeof requestAnimationFrame==`function`;function ke(e){var t,n=function(){clearTimeout(r),Oe&&cancelAnimationFrame(t),setTimeout(e)},r=setTimeout(n,35);Oe&&(t=requestAnimationFrame(n))}function Ae(e){e!=1&&P==L.requestAnimationFrame||((P=L.requestAnimationFrame)||ke)(De)}function je(e){var t=N,n=e.__c;typeof n==`function`&&(e.__c=void 0,n()),N=t}function Me(e){var t=N;e.__c=e.__(),N=t}function Ne(e,t){return!e||e.length!=t.length||t.some(function(t,n){return!F(t,e[n])})}function Pe(e,t){return typeof t==`function`?t(e):t}var Fe=0;Array.isArray;function H(e,n,r,i,a,o){n||={};var s,c,l=n;if(`ref`in l&&typeof e!=`function`)for(c in l={},n)c==`ref`?s=n[c]:l[c]=n[c];var u={type:e,props:l,key:r,ref:s,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:--Fe,__i:-1,__u:0};return(a||o)&&(u.__source=a,u.__self=o),t.vnode&&t.vnode(u),u}var Ie={eye:`M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12Z M12 9a3 3 0 1 0 0 6 3 3 0 0 0 0-6Z`,eyeOff:`M3 3l18 18 M10.6 5.1A10 10 0 0 1 12 5c6.5 0 10 7 10 7a17 17 0 0 1-3.2 4.2 M6.6 6.6A17 17 0 0 0 2 12s3.5 7 10 7a9.6 9.6 0 0 0 5.4-1.6 M9.9 9.9a3 3 0 0 0 4.2 4.2`,copy:`M9 9h11v11H9z M5 15H4V4h11v1`,plus:`M12 5v14 M5 12h14`,star:`M12 3l2.8 5.7 6.2.9-4.5 4.4 1.1 6.2L12 17.3 6.4 20.2l1.1-6.2L3 9.6l6.2-.9Z`,lock:`M6 11h12v10H6z M8 11V7a4 4 0 0 1 8 0v4`,settings:`M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1.1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.5-1.1 1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3H9a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8V9a1.7 1.7 0 0 0 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1Z`,trash:`M4 7h16 M10 11v6 M14 11v6 M6 7l1 13h10l1-13 M9 7V4h6v3`,back:`M15 18l-6-6 6-6`,check:`M5 12l5 5 9-10`,alert:`M12 3l10 18H2Z M12 10v4 M12 17.5v.5`,key:`M14 10a4 4 0 1 0-3.6 4L13 17h2v2h2v2h3v-3l-6.4-6.4A4 4 0 0 0 14 10Z`,seed:`M4 6h16 M4 12h16 M4 18h10`,shield:`M12 3l8 3v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6Z`,duplicate:`M8 8h12v12H8z M4 16V4h12`,archive:`M3 4h18v4H3z M5 8v12h14V8 M10 12h4`,x:`M6 6l12 12 M18 6L6 18`,search:`M11 4a7 7 0 1 0 0 14 7 7 0 0 0 0-14Z M20 20l-4-4`,chevron:`M9 6l6 6-6 6`,wallet:`M3 7h15a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H3z M3 7V5h13v2 M16 13.5h.01`,terminal:`M4 6l6 6-6 6 M12 19h8`,mail:`M3 6h18v12H3z M3 7l9 6 9-6`,code:`M8 6l-6 6 6 6 M16 6l6 6-6 6`,list:`M9 6h11 M9 12h11 M9 18h11 M4 6h.01 M4 12h.01 M4 18h.01`,clock:`M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18Z M12 7v5l3 2`,expand:`M7 9l5-5 5 5 M7 15l5 5 5-5`,collapse:`M7 4l5 5 5-5 M7 20l5-5 5 5`,sliders:`M4 6h16 M4 12h16 M4 18h16 M9 4v4 M15 10v4 M7 16v4`,download:`M12 4v11 M7 10l5 5 5-5 M5 20h14`,file:`M6 3h8l4 4v14H6z M14 3v4h4`,edit:`M4 20h4L19 9l-4-4L4 16Z M13.5 6.5l4 4`},U=({name:e,size:t=16,...n})=>H(`svg`,{width:t,height:t,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,"stroke-width":`2`,"stroke-linecap":`round`,"stroke-linejoin":`round`,"aria-hidden":`true`,...n,children:H(`path`,{d:Ie[e]})}),W=new TextEncoder,Le=new TextDecoder,G=e=>W.encode(e),Re=e=>Le.decode(e),ze=e=>Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``),Be=e=>{let t=e.startsWith(`0x`)||e.startsWith(`0X`)?e.slice(2):e;if(t.length%2!=0||/[^0-9a-fA-F]/.test(t))throw Error(`Invalid hex`);let n=new Uint8Array(t.length/2);for(let e=0;e{let t=``;for(let n=0;n{let t=atob(e),n=new Uint8Array(t.length);for(let e=0;eglobalThis.crypto!==void 0&&globalThis.crypto.subtle!==void 0,K=e=>e,We=async e=>new Uint8Array(await crypto.subtle.digest(`SHA-256`,K(e))),Ge=async(e,t)=>{let n=await crypto.subtle.importKey(`raw`,K(e),{name:`HMAC`,hash:`SHA-512`},!1,[`sign`]);return new Uint8Array(await crypto.subtle.sign(`HMAC`,n,K(t)))},Ke=(e,t)=>{if(e.length!==t.length)return!1;for(let n=0;n{let t=new Uint8Array(e);return crypto.getRandomValues(t),t},qe=()=>typeof crypto.randomUUID==`function`?crypto.randomUUID():ze(q(16)),Je=[`mnemonic`,`privateKey`,`sshKey`,`pgpKey`,`apiKey`,`genericKey`,`recoveryCodes`,`other`],J={mnemonic:{label:`Seed phrase`,one:`seed phrase`,plural:`seed phrases`,group:`crypto`,secret:`words`,secretLabel:`Seed phrase`,passphraseLabel:`Passphrase (25th word)`,passphraseHint:`Optional BIP39 passphrase. A different passphrase opens a different wallet.`,serviceLabel:`Chain / coin`,accountLabel:`Wallet / device`,expires:!1,backupReminders:!0},privateKey:{label:`Wallet key`,one:`wallet key`,plural:`wallet keys`,group:`crypto`,secret:`key`,secretLabel:`Private key`,secretPlaceholder:`Hex, WIF, xprv, nsec, base58, keystore JSON…`,passphraseLabel:`Keystore password`,passphraseHint:`Only for encrypted keystores (e.g. Ethereum JSON keystores).`,serviceLabel:`Chain / coin`,accountLabel:`Wallet / device`,expires:!1,backupReminders:!0},sshKey:{label:`SSH key`,one:`SSH key`,plural:`SSH keys`,group:`keys`,secret:`key`,secretLabel:`Private key`,secretPlaceholder:`-----BEGIN OPENSSH PRIVATE KEY-----`,passphraseLabel:`Key passphrase`,passphraseHint:`The passphrase that unlocks the key file, if it has one.`,publicKey:{label:`Public key`,placeholder:`ssh-ed25519 AAAA… user@host`,fingerprintLabel:`Fingerprint`,fingerprintPlaceholder:`SHA256:…`},serviceLabel:`Hosts / service`,accountLabel:`User / account`,expires:!0,backupReminders:!1},pgpKey:{label:`PGP key`,one:`PGP key`,plural:`PGP keys`,group:`keys`,secret:`key`,secretLabel:`Private key`,secretPlaceholder:`-----BEGIN PGP PRIVATE KEY BLOCK-----`,passphraseLabel:`Key passphrase`,passphraseHint:`The passphrase that protects the secret key.`,publicKey:{label:`Public key`,placeholder:`-----BEGIN PGP PUBLIC KEY BLOCK-----`,fingerprintLabel:`Fingerprint`,fingerprintPlaceholder:`40 hex characters`},serviceLabel:`Used for`,accountLabel:`User ID / email`,expires:!0,backupReminders:!0},apiKey:{label:`API key or token`,one:`API key`,plural:`API keys`,group:`keys`,secret:`token`,secretLabel:`Key or token`,secretPlaceholder:`Paste the key or token`,serviceLabel:`Service`,accountLabel:`Account / project`,expires:!0,backupReminders:!1},genericKey:{label:`Other key`,one:`other key`,plural:`other keys`,group:`keys`,secret:`key`,secretLabel:`Secret key`,secretPlaceholder:`age, WireGuard, PEM, JSON Web Key, Nostr…`,passphraseLabel:`Passphrase`,passphraseHint:`If the key is encrypted.`,publicKey:{label:`Public key`,placeholder:`Public key or recipient`,fingerprintLabel:`Fingerprint / key ID`,fingerprintPlaceholder:`Optional`},serviceLabel:`Used for`,accountLabel:`Account / owner`,expires:!0,backupReminders:!1},recoveryCodes:{label:`Recovery codes`,one:`set of recovery codes`,plural:`sets of recovery codes`,group:`secrets`,secret:`codes`,secretLabel:`Recovery codes`,secretPlaceholder:`One code per line`,serviceLabel:`Service`,accountLabel:`Account`,expires:!1,backupReminders:!0},other:{label:`Other secret`,one:`other secret`,plural:`other secrets`,group:`secrets`,secret:`fields`,secretLabel:`Fields`,serviceLabel:`Service`,accountLabel:`Account`,expires:!1,backupReminders:!1}},Ye={crypto:`Crypto`,keys:`Keys`,secrets:`Secrets`},Xe=e=>J[e].group===`crypto`,Ze=`keyfold`,Qe=`Managed by the Keyfold editor for Standard Notes (https://github.com/nickstruglia/standard-notes-keyfold). Open it with Keyfold; do not edit it as plain text or convert it to Super, which can damage the data. `,$e=Qe+`The vault below lists each entry with its label, kind and secret; seed phrase words are in order, and \\n in a value is a line break.`,et=e=>`The vault below is encrypted with ${e}: PBKDF2-SHA256 (password NFC-normalized, the salt and iteration count below) gives an AES-256-GCM key; the IV is below, the ciphertext ends with the 16-byte tag, the associated data is "keyfold|1|PBKDF2-SHA256||AES-256-GCM", and the plaintext is the vault as JSON.`,tt=Qe+et(`your vault password`),Y={autoHideSeconds:30,clipboardClearSeconds:30,hideOnBlur:!0,privacyScreen:!1,autoLockMinutes:5,backupReminderMonths:12,layout:`stacked`,density:`comfortable`,singleExpand:!1,lockSavedEntries:!0,groupBy:`kind`,sort:`updated`,lastExportedAt:``},nt=()=>{let e=new Date,t=e=>String(e).padStart(2,`0`);return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())}`},rt=()=>({entries:[],settings:{...Y}}),it=(e,t={})=>{let n=new Date().toISOString();return{id:qe(),kind:e,label:``,description:``,chain:``,wallet:``,service:``,account:``,createdOn:nt(),expiresOn:``,tags:[],favorite:!1,archived:!1,scheme:`bip39`,words:e===`mnemonic`?Array(12).fill(``):[],passphrase:``,passphraseHint:``,secret:``,derivationPath:``,fingerprint:``,publicInfo:``,backups:[],customFields:[],notes:``,addedAt:n,updatedAt:n,...t}},X=(e,t=``)=>typeof e==`string`?e:t,at=(e,t=!1)=>typeof e==`boolean`?e:t,ot=(e,t)=>typeof e==`number`&&Number.isFinite(e)&&e>=0?e:t,st=e=>Array.isArray(e)?e:[],ct=(e,t,n)=>t.includes(e)?e:n,lt=e=>e&&typeof e==`object`&&!Array.isArray(e)?e:{},ut=[`bip39`,`electrum`,`aezeed`,`slip39`,`monero`,`other`],dt=e=>{let t=lt(e),n=it(`other`);return{...t,id:X(t.id)||n.id,kind:Je.includes(t.kind)?t.kind:`other`,label:X(t.label),description:X(t.description),chain:X(t.chain),wallet:X(t.wallet),service:X(t.service),account:X(t.account),createdOn:X(t.createdOn),expiresOn:X(t.expiresOn),tags:st(t.tags).filter(e=>typeof e==`string`),favorite:at(t.favorite),archived:at(t.archived),scheme:ut.includes(t.scheme)?t.scheme:`bip39`,words:st(t.words).map(e=>X(e).normalize(`NFC`)),passphrase:X(t.passphrase),passphraseHint:X(t.passphraseHint),secret:X(t.secret),derivationPath:X(t.derivationPath),fingerprint:X(t.fingerprint),publicInfo:X(t.publicInfo),backups:st(t.backups).map(e=>{let t=lt(e);return{...t,id:X(t.id)||qe(),location:X(t.location),verifiedOn:X(t.verifiedOn)}}),customFields:st(t.customFields).map(e=>{let t=lt(e);return{...t,id:X(t.id)||qe(),label:X(t.label),value:X(t.value),hidden:at(t.hidden,!0),multiline:t.multiline===!0||X(t.value).includes(` +`)}}),notes:X(t.notes),addedAt:X(t.addedAt)||n.addedAt,updatedAt:X(t.updatedAt)||n.updatedAt}},ft={layout:[`stacked`,`split`],density:[`comfortable`,`compact`],groupBy:[`none`,`kind`,`chain`,`wallet`,`tag`],sort:[`updated`,`label`,`created`]},pt=new WeakSet,mt=e=>pt.has(e),ht=(e,t)=>st(e.entries).some(e=>{let t=lt(e);return t.kind!==void 0&&!Je.includes(t.kind)||t.scheme!==void 0&&!ut.includes(t.scheme)})||Object.entries(ft).some(([e,n])=>t[e]!==void 0&&!n.includes(t[e])),gt=(e,t,n)=>{let r=ot(e,t);return r>n?t:r},_t=e=>{let t=lt(e),n=lt(t.settings),r={...t,entries:st(t.entries).map(dt),settings:{...n,autoHideSeconds:gt(n.autoHideSeconds,Y.autoHideSeconds,86400),clipboardClearSeconds:gt(n.clipboardClearSeconds,Y.clipboardClearSeconds,86400),hideOnBlur:at(n.hideOnBlur,Y.hideOnBlur),privacyScreen:at(n.privacyScreen,Y.privacyScreen),autoLockMinutes:gt(n.autoLockMinutes,Y.autoLockMinutes,10080),backupReminderMonths:gt(n.backupReminderMonths,Y.backupReminderMonths,1200),layout:ct(n.layout,[`stacked`,`split`],Y.layout),density:ct(n.density,[`comfortable`,`compact`],Y.density),singleExpand:at(n.singleExpand,Y.singleExpand),lockSavedEntries:at(n.lockSavedEntries,Y.lockSavedEntries),groupBy:ct(n.groupBy,[`none`,`kind`,`chain`,`wallet`,`tag`],Y.groupBy),sort:ct(n.sort,[`updated`,`label`,`created`],Y.sort),lastExportedAt:X(n.lastExportedAt)}};return ht(t,n)&&pt.add(r),r},vt=e=>{let t=lt(e);return t.kdf===`PBKDF2-SHA256`&&t.cipher===`AES-256-GCM`&&typeof t.iterations==`number`&&Number.isInteger(t.iterations)&&t.iterations>=1e3&&t.iterations<=1e7&&typeof t.salt==`string`&&typeof t.iv==`string`&&typeof t.ciphertext==`string`},yt=e=>{let t=e?.replace(/^\uFEFF/,``);if(!t||!t.trim())return{kind:`empty`};let n;try{n=JSON.parse(t)}catch{return{kind:`foreign`,text:t}}let r=lt(n);if(r.app!==`keyfold`)return{kind:`foreign`,text:t};let i=typeof r.version==`number`?r.version:0;return i>1?{kind:`newer`,version:i}:r.encryption===void 0?{kind:`plain`,vault:_t(r.vault)}:vt(r.encryption)?typeof r.exportedAt==`string`?{kind:`encrypted`,blob:r.encryption,exportedAt:r.exportedAt}:{kind:`encrypted`,blob:r.encryption}:{kind:`unsupported`}},bt=e=>JSON.stringify({app:Ze,version:1,readme:$e,vault:e},null,1),xt=e=>JSON.stringify({app:Ze,version:1,readme:tt,encryption:e},null,1),St=e=>{if(!e)return`Keyfold (password protected)`;let t=e.entries.filter(e=>!e.archived),n=Je.flatMap(e=>{let n=t.filter(t=>t.kind===e).length;return n?[`${n} ${n===1?J[e].one:J[e].plural}`]:[]});return`Keyfold: ${n.length?n.join(`, `):`empty`}`},Ct=e=>e.backups.map(e=>e.verifiedOn).filter(Boolean).sort().pop()??``,wt=(e,t,n=new Date)=>{if(t<=0||e.archived||!J[e.kind].backupReminders)return!1;let r=Ct(e);if(!r)return!0;let i=new Date(`${r}T00:00:00`);return i.setMonth(i.getMonth()+t),i.getTime()<=n.getTime()},Tt=(e,t=new Date)=>{if(!e.expiresOn||!J[e.kind].expires)return null;let n=new Date(`${e.expiresOn}T00:00:00`);if(Number.isNaN(n.getTime()))return null;let r=new Date(t.getFullYear(),t.getMonth(),t.getDate());return Math.round((n.getTime()-r.getTime())/864e5)},Et=(e,t=new Date)=>{let n=Tt(e,t);return n!==null&&n<=30&&!e.archived},Dt=de({settings:Y,readOnly:!1,hideEpoch:0,copy:()=>void 0,toast:()=>void 0,confirm:async()=>!1,sectionOpen:(e,t)=>t,setSectionOpen:()=>void 0}),Z=()=>Te(Dt),Ot=(e,t)=>{let{sectionOpen:n,setSectionOpen:r}=Z();return[n(e,t),t=>r(e,t)]},kt=(e=!0)=>{let t=V(null);return B(()=>{e&&t.current?.focus()},[]),t},At=(e,t)=>{let[n,r]=z(void 0),i=V(0);return B(()=>{let t=++i.current;e().then(e=>t===i.current&&r(()=>e),()=>t===i.current&&r(void 0))},t),n},jt=e=>{let{hideEpoch:t,settings:n}=Z(),[r,i]=z(!1);return B(()=>i(!1),[t]),B(()=>{if(!r||!n.autoHideSeconds)return;let e=setTimeout(()=>i(!1),n.autoHideSeconds*1e3);return()=>clearTimeout(e)},[r,n.autoHideSeconds,e]),[r,i]},Mt=()=>typeof matchMedia==`function`&&matchMedia(`(pointer: coarse)`).matches,Nt={autocomplete:`off`,autoCorrect:`off`,autocapitalize:`off`,spellcheck:!1,"data-1p-ignore":`true`,"data-lpignore":`true`,"data-bwignore":`true`,"data-form-type":`other`,"data-secret":``},Pt={autoCorrect:`off`,autocapitalize:`off`,spellcheck:!1},Ft=({value:e,onInput:t,label:n,placeholder:r,multiline:i,mono:a,id:o,onMultilinePaste:s})=>{let{readOnly:c,copy:l}=Z(),[u,d]=jt(e),f=`input ${a?`mono`:``}`,p=V(null),[m,h]=z(!1);B(()=>{m&&u&&(p.current?.focus(),h(!1))},[m,u]);let g;return g=i&&!u?H(`button`,{type:`button`,class:`input masked-placeholder`,"aria-label":`${n} (hidden). Reveal to view or edit`,onClick:()=>{d(!0),h(!0)},children:e?`${`•`.repeat(12)} ${e.length} characters, hidden`:r||`Empty`}):i?H(`textarea`,{ref:p,id:o,class:f,value:e,rows:e.length>120?6:3,placeholder:r,"aria-label":n,readOnly:c,onInput:e=>t(e.currentTarget.value),...Nt}):H(`input`,{id:o,class:f,...u?{type:`text`}:{type:`password`},value:e,placeholder:r,"aria-label":n,readOnly:c,onInput:e=>t(e.currentTarget.value),onPaste:t=>{let n=t.clipboardData?.getData(`text`)??``;if(!s||!/[\r\n]/.test(n))return;t.preventDefault();let r=t.currentTarget,i=r.selectionStart??e.length,a=r.selectionEnd??e.length;s(e.slice(0,i)+n+e.slice(a))},...Nt}),H(`div`,{class:`secret ${i?`secret-multiline`:``}`,children:[g,H(`div`,{class:`secret-actions`,children:[H(`button`,{type:`button`,class:`icon-button`,title:u?`Hide`:`Reveal`,"aria-label":`${u?`Hide`:`Reveal`} ${n}`,onClick:()=>d(!u),children:H(U,{name:u?`eyeOff`:`eye`})}),H(`button`,{type:`button`,class:`icon-button`,title:`Copy`,"aria-label":`Copy ${n}`,disabled:!e,onClick:()=>l(e,n),children:H(U,{name:`copy`})})]})]})},It=`abandon ability able about above absent absorb abstract + absurd abuse access accident account accuse achieve acid + acoustic acquire across act action actor actress actual + adapt add addict address adjust admit adult advance + advice aerobic affair afford afraid again age agent + agree ahead aim air airport aisle alarm album + alcohol alert alien all alley allow almost alone + alpha already also alter always amateur amazing among + amount amused analyst anchor ancient anger angle angry + animal ankle announce annual another answer antenna antique + anxiety any apart apology appear apple approve april + arch arctic area arena argue arm armed armor + army around arrange arrest arrive arrow art artefact + artist artwork ask aspect assault asset assist assume + asthma athlete atom attack attend attitude attract auction + audit august aunt author auto autumn average avocado + avoid awake aware away awesome awful awkward axis + baby bachelor bacon badge bag balance balcony ball + bamboo banana banner bar barely bargain barrel base + basic basket battle beach bean beauty because become + beef before begin behave behind believe below belt + bench benefit best betray better between beyond bicycle + bid bike bind biology bird birth bitter black + blade blame blanket blast bleak bless blind blood + blossom blouse blue blur blush board boat body + boil bomb bone bonus book boost border boring + borrow boss bottom bounce box boy bracket brain + brand brass brave bread breeze brick bridge brief + bright bring brisk broccoli broken bronze broom brother + brown brush bubble buddy budget buffalo build bulb + bulk bullet bundle bunker burden burger burst bus + business busy butter buyer buzz cabbage cabin cable + cactus cage cake call calm camera camp can + canal cancel candy cannon canoe canvas canyon capable + capital captain car carbon card cargo carpet carry + cart case cash casino castle casual cat catalog + catch category cattle caught cause caution cave ceiling + celery cement census century cereal certain chair chalk + champion change chaos chapter charge chase chat cheap + check cheese chef cherry chest chicken chief child + chimney choice choose chronic chuckle chunk churn cigar + cinnamon circle citizen city civil claim clap clarify + claw clay clean clerk clever click client cliff + climb clinic clip clock clog close cloth cloud + clown club clump cluster clutch coach coast coconut + code coffee coil coin collect color column combine + come comfort comic common company concert conduct confirm + congress connect consider control convince cook cool copper + copy coral core corn correct cost cotton couch + country couple course cousin cover coyote crack cradle + craft cram crane crash crater crawl crazy cream + credit creek crew cricket crime crisp critic crop + cross crouch crowd crucial cruel cruise crumble crunch + crush cry crystal cube culture cup cupboard curious + current curtain curve cushion custom cute cycle dad + damage damp dance danger daring dash daughter dawn + day deal debate debris decade december decide decline + decorate decrease deer defense define defy degree delay + deliver demand demise denial dentist deny depart depend + deposit depth deputy derive describe desert design desk + despair destroy detail detect develop device devote diagram + dial diamond diary dice diesel diet differ digital + dignity dilemma dinner dinosaur direct dirt disagree discover + disease dish dismiss disorder display distance divert divide + divorce dizzy doctor document dog doll dolphin domain + donate donkey donor door dose double dove draft + dragon drama drastic draw dream dress drift drill + drink drip drive drop drum dry duck dumb + dune during dust dutch duty dwarf dynamic eager + eagle early earn earth easily east easy echo + ecology economy edge edit educate effort egg eight + either elbow elder electric elegant element elephant elevator + elite else embark embody embrace emerge emotion employ + empower empty enable enact end endless endorse enemy + energy enforce engage engine enhance enjoy enlist enough + enrich enroll ensure enter entire entry envelope episode + equal equip era erase erode erosion error erupt + escape essay essence estate eternal ethics evidence evil + evoke evolve exact example excess exchange excite exclude + excuse execute exercise exhaust exhibit exile exist exit + exotic expand expect expire explain expose express extend + extra eye eyebrow fabric face faculty fade faint + faith fall false fame family famous fan fancy + fantasy farm fashion fat fatal father fatigue fault + favorite feature february federal fee feed feel female + fence festival fetch fever few fiber fiction field + figure file film filter final find fine finger + finish fire firm first fiscal fish fit fitness + fix flag flame flash flat flavor flee flight + flip float flock floor flower fluid flush fly + foam focus fog foil fold follow food foot + force forest forget fork fortune forum forward fossil + foster found fox fragile frame frequent fresh friend + fringe frog front frost frown frozen fruit fuel + fun funny furnace fury future gadget gain galaxy + gallery game gap garage garbage garden garlic garment + gas gasp gate gather gauge gaze general genius + genre gentle genuine gesture ghost giant gift giggle + ginger giraffe girl give glad glance glare glass + glide glimpse globe gloom glory glove glow glue + goat goddess gold good goose gorilla gospel gossip + govern gown grab grace grain grant grape grass + gravity great green grid grief grit grocery group + grow grunt guard guess guide guilt guitar gun + gym habit hair half hammer hamster hand happy + harbor hard harsh harvest hat have hawk hazard + head health heart heavy hedgehog height hello helmet + help hen hero hidden high hill hint hip + hire history hobby hockey hold hole holiday hollow + home honey hood hope horn horror horse hospital + host hotel hour hover hub huge human humble + humor hundred hungry hunt hurdle hurry hurt husband + hybrid ice icon idea identify idle ignore ill + illegal illness image imitate immense immune impact impose + improve impulse inch include income increase index indicate + indoor industry infant inflict inform inhale inherit initial + inject injury inmate inner innocent input inquiry insane + insect inside inspire install intact interest into invest + invite involve iron island isolate issue item ivory + jacket jaguar jar jazz jealous jeans jelly jewel + job join joke journey joy judge juice jump + jungle junior junk just kangaroo keen keep ketchup + key kick kid kidney kind kingdom kiss kit + kitchen kite kitten kiwi knee knife knock know + lab label labor ladder lady lake lamp language + laptop large later latin laugh laundry lava law + lawn lawsuit layer lazy leader leaf learn leave + lecture left leg legal legend leisure lemon lend + length lens leopard lesson letter level liar liberty + library license life lift light like limb limit + link lion liquid list little live lizard load + loan lobster local lock logic lonely long loop + lottery loud lounge love loyal lucky luggage lumber + lunar lunch luxury lyrics machine mad magic magnet + maid mail main major make mammal man manage + mandate mango mansion manual maple marble march margin + marine market marriage mask mass master match material + math matrix matter maximum maze meadow mean measure + meat mechanic medal media melody melt member memory + mention menu mercy merge merit merry mesh message + metal method middle midnight milk million mimic mind + minimum minor minute miracle mirror misery miss mistake + mix mixed mixture mobile model modify mom moment + monitor monkey monster month moon moral more morning + mosquito mother motion motor mountain mouse move movie + much muffin mule multiply muscle museum mushroom music + must mutual myself mystery myth naive name napkin + narrow nasty nation nature near neck need negative + neglect neither nephew nerve nest net network neutral + never news next nice night noble noise nominee + noodle normal north nose notable note nothing notice + novel now nuclear number nurse nut oak obey + object oblige obscure observe obtain obvious occur ocean + october odor off offer office often oil okay + old olive olympic omit once one onion online + only open opera opinion oppose option orange orbit + orchard order ordinary organ orient original orphan ostrich + other outdoor outer output outside oval oven over + own owner oxygen oyster ozone pact paddle page + pair palace palm panda panel panic panther paper + parade parent park parrot party pass patch path + patient patrol pattern pause pave payment peace peanut + pear peasant pelican pen penalty pencil people pepper + perfect permit person pet phone photo phrase physical + piano picnic picture piece pig pigeon pill pilot + pink pioneer pipe pistol pitch pizza place planet + plastic plate play please pledge pluck plug plunge + poem poet point polar pole police pond pony + pool popular portion position possible post potato pottery + poverty powder power practice praise predict prefer prepare + present pretty prevent price pride primary print priority + prison private prize problem process produce profit program + project promote proof property prosper protect proud provide + public pudding pull pulp pulse pumpkin punch pupil + puppy purchase purity purpose purse push put puzzle + pyramid quality quantum quarter question quick quit quiz + quote rabbit raccoon race rack radar radio rail + rain raise rally ramp ranch random range rapid + rare rate rather raven raw razor ready real + reason rebel rebuild recall receive recipe record recycle + reduce reflect reform refuse region regret regular reject + relax release relief rely remain remember remind remove + render renew rent reopen repair repeat replace report + require rescue resemble resist resource response result retire + retreat return reunion reveal review reward rhythm rib + ribbon rice rich ride ridge rifle right rigid + ring riot ripple risk ritual rival river road + roast robot robust rocket romance roof rookie room + rose rotate rough round route royal rubber rude + rug rule run runway rural sad saddle sadness + safe sail salad salmon salon salt salute same + sample sand satisfy satoshi sauce sausage save say + scale scan scare scatter scene scheme school science + scissors scorpion scout scrap screen script scrub sea + search season seat second secret section security seed + seek segment select sell seminar senior sense sentence + series service session settle setup seven shadow shaft + shallow share shed shell sheriff shield shift shine + ship shiver shock shoe shoot shop short shoulder + shove shrimp shrug shuffle shy sibling sick side + siege sight sign silent silk silly silver similar + simple since sing siren sister situate six size + skate sketch ski skill skin skirt skull slab + slam sleep slender slice slide slight slim slogan + slot slow slush small smart smile smoke smooth + snack snake snap sniff snow soap soccer social + sock soda soft solar soldier solid solution solve + someone song soon sorry sort soul sound soup + source south space spare spatial spawn speak special + speed spell spend sphere spice spider spike spin + spirit split spoil sponsor spoon sport spot spray + spread spring spy square squeeze squirrel stable stadium + staff stage stairs stamp stand start state stay + steak steel stem step stereo stick still sting + stock stomach stone stool story stove strategy street + strike strong struggle student stuff stumble style subject + submit subway success such sudden suffer sugar suggest + suit summer sun sunny sunset super supply supreme + sure surface surge surprise surround survey suspect sustain + swallow swamp swap swarm swear sweet swift swim + swing switch sword symbol symptom syrup system table + tackle tag tail talent talk tank tape target + task taste tattoo taxi teach team tell ten + tenant tennis tent term test text thank that + theme then theory there they thing this thought + three thrive throw thumb thunder ticket tide tiger + tilt timber time tiny tip tired tissue title + toast tobacco today toddler toe together toilet token + tomato tomorrow tone tongue tonight tool tooth top + topic topple torch tornado tortoise toss total tourist + toward tower town toy track trade traffic tragic + train transfer trap trash travel tray treat tree + trend trial tribe trick trigger trim trip trophy + trouble truck true truly trumpet trust truth try + tube tuition tumble tuna tunnel turkey turn turtle + twelve twenty twice twin twist two type typical + ugly umbrella unable unaware uncle uncover under undo + unfair unfold unhappy uniform unique unit universe unknown + unlock until unusual unveil update upgrade uphold upon + upper upset urban urge usage use used useful + useless usual utility vacant vacuum vague valid valley + valve van vanish vapor various vast vault vehicle + velvet vendor venture venue verb verify version very + vessel veteran viable vibrant vicious victory video view + village vintage violin virtual virus visa visit visual + vital vivid vocal voice void volcano volume vote + voyage wage wagon wait walk wall walnut want + warfare warm warrior wash wasp waste water wave + way wealth weapon wear weasel weather web wedding + weekend weird welcome west wet whale what wheat + wheel when where whip whisper wide width wife + wild will win window wine wing wink winner + winter wire wisdom wise wish witness wolf woman + wonder wood wool word work world worry worth + wrap wreck wrestle wrist write wrong yard year + yellow you young youth zebra zero zone zoo`.split(/\s+/),Lt=`Copyright (c) 2014-2024, The Monero Project +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other + materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be + used to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.`,Rt=`abbey abducts ability ablaze abnormal abort abrasive absorb + abyss academy aces aching acidic acoustic acquire across + actress acumen adapt addicted adept adhesive adjust adopt + adrenalin adult adventure aerial afar affair afield afloat + afoot afraid after against agenda aggravate agile aglow + agnostic agony agreed ahead aided ailments aimless airport + aisle ajar akin alarms album alchemy alerts algebra + alkaline alley almost aloof alpine already also altitude + alumni always amaze ambush amended amidst ammo amnesty + among amply amused anchor android anecdote angled ankle + annoyed answers antics anvil anxiety anybody apart apex + aphid aplomb apology apply apricot aptitude aquarium arbitrary + archer ardent arena argue arises army around arrow + arsenic artistic ascend ashtray aside asked asleep aspire + assorted asylum athlete atlas atom atrium attire auburn + auctions audio august aunt austere autumn avatar avidly + avoid awakened awesome awful awkward awning awoken axes + axis axle aztec azure baby bacon badge baffles + bagpipe bailed bakery balding bamboo banjo baptism basin + batch bawled bays because beer befit begun behind + being below bemused benches berries bested betting bevel + beware beyond bias bicycle bids bifocals biggest bikini + bimonthly binocular biology biplane birth biscuit bite biweekly + blender blip bluntly boat bobsled bodies bogeys boil + boldly bomb border boss both bounced bovine bowling + boxes boyfriend broken brunt bubble buckets budget buffet + bugs building bulb bumper bunch business butter buying + buzzer bygones byline bypass cabin cactus cadets cafe + cage cajun cake calamity camp candy casket catch + cause cavernous cease cedar ceiling cell cement cent + certain chlorine chrome cider cigar cinema circle cistern + citadel civilian claim click clue coal cobra cocoa + code coexist coffee cogs cohesive coils colony comb + cool copy corrode costume cottage cousin cowl criminal + cube cucumber cuddled cuffs cuisine cunning cupcake custom + cycling cylinder cynical dabbing dads daft dagger daily + damp dangerous dapper darted dash dating dauntless dawn + daytime dazed debut decay dedicated deepest deftly degrees + dehydrate deity dejected delayed demonstrate dented deodorant depth + desk devoid dewdrop dexterity dialect dice diet different + digit dilute dime dinner diode diplomat directed distance + ditch divers dizzy doctor dodge does dogs doing + dolphin domestic donuts doorway dormant dosage dotted double + dove down dozen dreams drinks drowning drunk drying + dual dubbed duckling dude duets duke dullness dummy + dunes duplex duration dusted duties dwarf dwelt dwindling + dying dynamite dyslexic each eagle earth easy eating + eavesdrop eccentric echo eclipse economics ecstatic eden edgy + edited educated eels efficient eggs egotistic eight either + eject elapse elbow eldest eleven elite elope else + eluded emails ember emerge emit emotion empty emulate + energy enforce enhanced enigma enjoy enlist enmity enough + enraged ensign entrance envy epoxy equip erase erected + erosion error eskimos espionage essential estate etched eternal + ethics etiquette evaluate evenings evicted evolved examine excess + exhale exit exotic exquisite extra exult fabrics factual + fading fainted faked fall family fancy farming fatal + faulty fawns faxed fazed feast february federal feel + feline females fences ferry festival fetches fever fewest + fiat fibula fictional fidget fierce fifteen fight films + firm fishing fitting five fixate fizzle fleet flippant + flying foamy focus foes foggy foiled folding fonts + foolish fossil fountain fowls foxes foyer framed friendly + frown fruit frying fudge fuel fugitive fully fuming + fungal furnished fuselage future fuzzy gables gadget gags + gained galaxy gambit gang gasp gather gauze gave + gawk gaze gearbox gecko geek gels gemstone general + geometry germs gesture getting geyser ghetto ghost giant + giddy gifts gigantic gills gimmick ginger girth giving + glass gleeful glide gnaw gnome goat goblet godfather + goes goggles going goldfish gone goodbye gopher gorilla + gossip gotten gourmet governing gown greater grunt guarded + guest guide gulp gumball guru gusts gutter guys + gymnast gypsy gyrate habitat hacksaw haggled hairy hamburger + happens hashing hatchet haunted having hawk haystack hazard + hectare hedgehog heels hefty height hemlock hence heron + hesitate hexagon hickory hiding highway hijack hiker hills + himself hinder hippo hire history hitched hive hoax + hobby hockey hoisting hold honked hookup hope hornet + hospital hotel hounded hover howls hubcaps huddle huge + hull humid hunter hurried husband huts hybrid hydrogen + hyper iceberg icing icon identity idiom idled idols + igloo ignore iguana illness imagine imbalance imitate impel + inactive inbound incur industrial inexact inflamed ingested initiate + injury inkling inline inmate innocent inorganic input inquest + inroads insult intended inundate invoke inwardly ionic irate + iris irony irritate island isolated issued italics itches + items itinerary itself ivory jabbed jackets jaded jagged + jailed jamming january jargon jaunt javelin jaws jazz + jeans jeers jellyfish jeopardy jerseys jester jetting jewels + jigsaw jingle jittery jive jobs jockey jogger joining + joking jolted jostle journal joyous jubilee judge juggled + juicy jukebox july jump junk jury justice juvenile + kangaroo karate keep kennel kept kernels kettle keyboard + kickoff kidneys king kiosk kisses kitchens kiwi knapsack + knee knife knowledge knuckle koala laboratory ladder lagoon + lair lakes lamb language laptop large last later + launching lava lawsuit layout lazy lectures ledge leech + left legion leisure lemon lending leopard lesson lettuce + lexicon liar library licks lids lied lifestyle light + likewise lilac limits linen lion lipstick liquid listen + lively loaded lobster locker lodge lofty logic loincloth + long looking lopped lordship losing lottery loudly love + lower loyal lucky luggage lukewarm lullaby lumber lunar + lurk lush luxury lymph lynx lyrics macro madness + magically mailed major makeup malady mammal maps masterful + match maul maverick maximum mayor maze meant mechanic + medicate meeting megabyte melting memoir menu merger mesh + metro mews mice midst mighty mime mirror misery + mittens mixture moat mobile mocked mohawk moisture molten + moment money moon mops morsel mostly motherly mouth + movement mowing much muddy muffin mugged mullet mumble + mundane muppet mural musical muzzle myriad mystery myth + nabbing nagged nail names nanny napkin narrate nasty + natural nautical navy nearby necklace needed negative neither + neon nephew nerves nestle network neutral never newt + nexus nibs niche niece nifty nightly nimbly nineteen + nirvana nitrogen nobody nocturnal nodes noises nomad noodles + northern nostril noted nouns novelty nowhere nozzle nuance + nucleus nudged nugget nuisance null number nuns nurse + nutshell nylon oaks oars oasis oatmeal obedient object + obliged obnoxious observant obtains obvious occur ocean october + odds odometer offend often oilfield ointment okay older + olive olympics omega omission omnibus onboard oncoming oneself + ongoing onion online onslaught onto onward oozed opacity + opened opposite optical opus orange orbit orchid orders + organs origin ornament orphans oscar ostrich otherwise otter + ouch ought ounce ourselves oust outbreak oval oven + owed owls owner oxidant oxygen oyster ozone pact + paddles pager pairing palace pamphlet pancakes paper paradise + pastry patio pause pavements pawnshop payment peaches pebbles + peculiar pedantic peeled pegs pelican pencil people pepper + perfect pests petals phase pheasants phone phrases physics + piano picked pierce pigment piloted pimple pinched pioneer + pipeline pirate pistons pitched pivot pixels pizza playful + pledge pliers plotting plus plywood poaching pockets podcast + poetry point poker polar ponies pool popular portents + possible potato pouch poverty powder pram present pride + problems pruned prying psychic public puck puddle puffin + pulp pumpkins punch puppy purged push putty puzzled + pylons pyramid python queen quick quote rabbits racetrack + radar rafts rage railway raking rally ramped randomly + rapid rarest rash rated ravine rays razor react + rebel recipe reduce reef refer regular reheat reinvest + rejoices rekindle relic remedy renting reorder repent request + reruns rest return reunion revamp rewind rhino rhythm + ribbon richly ridges rift rigid rims ringing riots + ripped rising ritual river roared robot rockets rodent + rogue roles romance roomy roped roster rotate rounded + rover rowboat royal ruby rudely ruffled rugged ruined + ruling rumble runway rural rustled ruthless sabotage sack + sadness safety saga sailor sake salads sample sanity + sapling sarcasm sash satin saucepan saved sawmill saxophone + sayings scamper scenic school science scoop scrub scuba + seasons second sedan seeded segments seismic selfish semifinal + sensible september sequence serving session setup seventh sewage + shackles shelter shipped shocking shrugged shuffled shyness siblings + sickness sidekick sieve sifting sighting silk simplest sincerely + sipped siren situated sixteen sizes skater skew skirting + skulls skydive slackens sleepless slid slower slug smash + smelting smidgen smog smuggled snake sneeze sniff snout + snug soapy sober soccer soda software soggy soil + solved somewhere sonic soothe soprano sorry southern sovereign + sowed soya space speedy sphere spiders splendid spout + sprig spud spying square stacking stellar stick stockpile + strained stunning stylishly subtly succeed suddenly suede suffice + sugar suitcase sulking summon sunken superior surfer sushi + suture swagger swept swiftly sword swung syllabus symptoms + syndrome syringe system taboo tacit tadpoles tagged tail + taken talent tamper tanks tapestry tarnished tasked tattoo + taunts tavern tawny taxi teardrop technical tedious teeming + tell template tender tepid tequila terminal testing tether + textbook thaw theatrics thirsty thorn threaten thumbs thwart + ticket tidy tiers tiger tilt timber tinted tipsy + tirade tissue titans toaster tobacco today toenail toffee + together toilet token tolerant tomorrow tonic toolbox topic + torch tossed total touchy towel toxic toyed trash + trendy tribal trolling truth trying tsunami tubes tucks + tudor tuesday tufts tugs tuition tulips tumbling tunnel + turnip tusks tutor tuxedo twang tweezers twice twofold + tycoon typist tyrant ugly ulcers ultimate umbrella umpire + unafraid unbending uncle under uneven unfit ungainly unhappy + union unjustly unknown unlikely unmask unnoticed unopened unplugs + unquoted unrest unsafe until unusual unveil unwind unzip + upbeat upcoming update upgrade uphill upkeep upload upon + upper upright upstairs uptight upwards urban urchins urgent + usage useful usher using usual utensils utility utmost + utopia uttered vacation vague vain value vampire vane + vapidly vary vastness vats vaults vector veered vegan + vehicle vein velvet venomous verification vessel veteran vexed + vials vibrate victim video viewpoint vigilant viking village + vinegar violin vipers virtual visited vitals vivid vixen + vocal vogue voice volcano vortex voted voucher vowels + voyage vulture wade waffle wagtail waist waking wallets + wanted warped washing water waveform waxing wayside weavers + website wedge weekday weird welders went wept were + western wetsuit whale when whipped whole wickets width + wield wife wiggle wildly winter wipeout wiring wise + withdrawn wives wizard wobbly woes woken wolf womanly + wonders woozy worry wounded woven wrap wrist wrong + yacht yahoo yanks yard yawning yearbook yellow yesterday + yeti yields yodel yoga younger yoyo zapped zeal + zebra zero zesty zigzags zinger zippers zodiac zombie + zones zoom`.split(/\s+/),zt=[{id:`bip39`,label:`BIP39 (English)`,counts:[12,15,18,21,24]},{id:`electrum`,label:`Electrum`,counts:[12]},{id:`aezeed`,label:`Aezeed (LND)`,counts:[24]},{id:`slip39`,label:`SLIP-39 share (Shamir)`,counts:[20,33]},{id:`monero`,label:`Monero`,counts:[25,13,16]},{id:`other`,label:`Other`,counts:[]}],Bt=[12,13,15,16,18,20,21,24,25,33],Vt=e=>e===`bip39`||e===`electrum`||e===`aezeed`,Ht=new Map(It.map((e,t)=>[e,t])),Ut=e=>e.normalize(`NFKD`).trim().toLowerCase(),Wt=e=>e.normalize(`NFC`).trim().toLowerCase(),Gt=e=>Ht.has(Ut(e)),Kt=/[\u200B-\u200D\u2060\uFEFF]/g,qt=/[\p{L}\p{M}\p{N}]/u,Jt=e=>{let t=[...e],n=0,r=t.length;for(;nn&&!qt.test(t[r-1]);)r--;return t.slice(n,r).join(``)},Yt=e=>{let t=e.replace(Kt,` `).replace(/(?{if(/^\p{L}[.)]$/u.test(e))return[];let t=Jt(e);return t?/^\d+$/.test(t)?[{n:Number(t)}]:/\p{L}/u.test(t)?[{word:Wt(t)}]:[]:[]}),n=t.flatMap((e,t)=>`n`in e?[t]:[]),r=n.map(e=>t[e-1]);if(n.length>1&&r.every(e=>e&&`word`in e&&e.word===r[0].word))for(let e of n.reverse())t.splice(e-1,1);let i=[],a=[],o=null,s=!0;for(let e of t)`n`in e?o=e.n:(a.push(e.word),o===null?s=!1:i.push({n:o,word:e.word}),o=null);if(s&&a.length>1){let e=[...i].sort((e,t)=>e.n-t.n);if(e.every((t,n)=>t.n===e[0].n+n)&&e[0].n>=1)return{words:e.map(e=>e.word),firstNumber:e[0].n,reordered:e.some((e,t)=>e!==i[t])}}return{words:a,reordered:!1}},Xt=e=>Yt(e).words,Zt=e=>{let t=Ut(e);if(t.length<4||Ht.has(t))return Wt(e);let n=It.filter(e=>e.startsWith(t));return n.length===1?n[0]:Wt(e)},Qt=(e,t)=>{let n=Array.from({length:t.length+1},(e,t)=>t);for(let r=1;r<=e.length;r++){let i=n[0];n[0]=r;for(let a=1;a<=t.length;a++){let o=n[a];n[a]=Math.min(n[a]+1,n[a-1]+1,i+(e[r-1]===t[a-1]?0:1)),i=o}}return n[t.length]},$t=(e,t=3)=>{let n=Ut(e);if(!n||n.length>10)return[];let r=It.filter(e=>e.startsWith(n.slice(0,4)));return r.length>0&&r.length<=t?r:It.map(e=>[e,Qt(n,e)]).filter(([,e])=>e<=2).sort((e,t)=>e[1]-t[1]).slice(0,t).map(([e])=>e)},en=async e=>{let t=e.length*11,n=t/33,r=t-n,i=e.map(e=>e.toString(2).padStart(11,`0`)).join(``),a=new Uint8Array(r/8);for(let e=0;ee.toString(2).padStart(8,`0`)).join(``);return i.slice(r)===s.slice(0,n)},tn=[[`01`,`standard`],[`100`,`segwit`],[`101`,`2fa`],[`102`,`2fa-segwit`]],nn=async e=>{let t=e.map(e=>Ut(e).replace(/[̀-ͯ]/g,``)).join(` `),n=ze(await Ge(G(`Seed version`),G(t)));return tn.find(([e])=>n.startsWith(e))?.[1]??null},rn=async(e,t)=>{let n=t.map(Ut),r=n.filter(Boolean).length,i=Vt(e)?n.flatMap((e,t)=>e&&!Ht.has(e)?[t]:[]):[];if(r===0)return{status:`incomplete`,message:`No words entered yet.`,unknownWords:i};if(r0)return{status:`invalid`,message:`Not in the English BIP39 wordlist: ${i.map(e=>`#${e+1}`).join(`, `)}. For other languages or old Electrum seeds, choose Other.`,unknownWords:i};if(!Ue()&&(e===`bip39`||e===`electrum`))return{status:`unchecked`,message:`Checksum check needs a secure (https) context.`,unknownWords:i};switch(e){case`bip39`:{if(![12,15,18,21,24].includes(n.length))return{status:`invalid`,message:`BIP39 phrases have 12, 15, 18, 21 or 24 words (this has ${n.length}).`,unknownWords:i};if(await en(n.map(e=>Ht.get(e))))return{status:`valid`,message:`Valid BIP39 checksum (${n.length} words).`,unknownWords:i};let e=n.length===12?await nn(n):null,t=n.length===24&&cn(n.map(e=>Ht.get(e)))===`valid`;return{status:`invalid`,message:e?`BIP39 checksum mismatch. The words do pass Electrum's check (${e} seed): if this seed came from Electrum, choose the Electrum scheme; otherwise check every word.`:t?`Not a BIP39 phrase, but these words are a valid aezeed seed. Choose the Aezeed (LND) scheme.`:`Checksum mismatch. Check the spelling and order of every word.`,unknownWords:i}}case`electrum`:{let e=await nn(n);return e?{status:`valid`,message:`Valid Electrum seed (${e}).`,unknownWords:i}:{status:`invalid`,message:`Not a valid Electrum 2.0+ seed. Check the words, or pick another scheme.`,unknownWords:i}}case`monero`:{if(n.length!==25&&n.length!==13)break;if(n.filter(e=>dn.has(e)).lengthfn.has(un(e))?[]:[t]);return e.length>0?{status:`invalid`,message:`Not in the Monero English wordlist: ${e.map(e=>`#${e+1}`).join(`, `)}.`,unknownWords:e}:pn(n)?{status:`valid`,message:`Monero checksum word OK (English, ${n.length} words).`,unknownWords:i}:{status:`invalid`,message:`The last word does not match the Monero checksum. Check the spelling and order of every word.`,unknownWords:i}}case`aezeed`:{if(n.length!==24)return{status:`invalid`,message:`Aezeed seeds have 24 words (this has ${n.length}).`,unknownWords:i};let e=n.map(e=>Ht.get(e)),t=cn(e);return t===`valid`?{status:`valid`,message:`Valid aezeed checksum. A seed password, if it has one, is not checked.`,unknownWords:i}:{status:`invalid`,message:t===`version`&&Ue()&&await en(e)?`Not an aezeed seed, but these words pass the BIP39 checksum. Choose the BIP39 scheme.`:t===`version`?`The first word does not match a known aezeed version. Check it, or pick another scheme.`:`Checksum mismatch. Check the spelling and order of every word.`,unknownWords:i}}}return{status:`unchecked`,message:`${n.length} words. Checksums for this scheme are not checked here.`,unknownWords:i}},an=3988292384,on=2197175160,sn=(e,t=an)=>{let n=4294967295;for(let r of e){let e=(n^r)&255;for(let n=0;n<8;n++)e=e&1?e>>>1^t:e>>>1;n=n>>>8^e}return(n^4294967295)>>>0},cn=e=>{let t=new Uint8Array(33),n=0,r=0,i=0;for(let a of e){for(n=n<<11|a,r+=11;r>=8;)r-=8,t[i++]=n>>>r&255;n&=(1<[...e].slice(0,ln).join(``),dn=new Set(Rt),fn=new Set(Rt.map(un)),pn=e=>{let t=e.slice(0,-1),n=e[e.length-1];return un(t[sn(G(t.map(un).join(``)))%t.length])===un(n)},mn=({words:e,scheme:t,unknownWords:n,onChange:r})=>{let{readOnly:i,copy:a,settings:o}=Z(),[s,c]=jt(e),[l,u]=z(null),[d,f]=z(null),[p,m]=z(``),h=V([]),g=V(new WeakSet),_=Vt(t),v=!Mt();B(()=>{if(d===null||!o.autoHideSeconds)return;let e=setTimeout(()=>f(null),o.autoHideSeconds*1e3);return()=>clearTimeout(e)},[d,e,o.autoHideSeconds]);let y=(t,n)=>{let i=[...e];i[t]=n,r(i)},b=(t,n)=>{let i=Math.min(48,Math.max(e.length,t+n.length)),a=Array.from({length:i},(t,n)=>e[n]??``);n.slice(0,i-t).forEach((e,n)=>a[t+n]=e),r(a),h.current[Math.min(t+n.length,i-1)]?.focus()},x=(e,t)=>{let n=Yt(t.clipboardData?.getData(`text`)??``);if(n.words.length<2)return;t.preventDefault();let r=n.firstNumber!==void 0&&n.firstNumber-1<48?n.firstNumber-1:e;b(r,n.words),m(n.reordered?`Placed the pasted words by their numbers. Check the order.`:``)},S=(e,t)=>{let n=t.currentTarget,r=n.value;t.isComposing?y(e,r):C(e,n)},C=(e,t)=>{let n=t.value;if(!/\s/.test(n)){let r=n.toLowerCase();if(r!==n){let[e,n]=[t.selectionStart,t.selectionEnd];t.value=r,e!==null&&n!==null&&t.setSelectionRange(e,n)}y(e,r);return}let r=Xt(n);r.length>1?b(e,r):(y(e,r[0]??``),r.length===1&&h.current[e+1]?.focus())},w=(t,n)=>{n.isComposing||n.keyCode===229||(n.key===` `||n.key===`Enter`?(n.preventDefault(),h.current[t+1]?.focus()):n.key===`Backspace`&&!e[t]&&t>0?(n.preventDefault(),h.current[t-1]?.focus()):v&&(n.key.length===1||n.key===`Backspace`)&&!n.ctrlKey&&!n.metaKey&&f(t))},T=()=>{u(null),f(null)},E=(e,t)=>{y(e,t),h.current[e]?.focus()},D=_?n.map(t=>[t,Zt(e[t]??``)]).filter(([t,n])=>n!==e[t]&&Gt(n)):[],O=D.length>0&&D.length===n.length,ee=()=>{let t=[...e];for(let[e,n]of D)t[e]=n;r(t)},te=e.filter(Boolean),k=e=>s||v&&d===e,ne=l!==null&&n.includes(l)&&e[l],re=_&&ne&&k(l)?$t(e[l]):[];return H(`div`,{class:`word-grid-wrap`,children:[H(`div`,{class:`word-toolbar`,children:[H(`button`,{type:`button`,class:`button small`,onClick:()=>c(!s),children:[H(U,{name:s?`eyeOff`:`eye`}),` `,s?`Hide words`:`Reveal words`]}),H(`button`,{type:`button`,class:`button small`,disabled:te.length===0,onClick:()=>a(te.join(` `),te.length===e.length?`Seed phrase`:`Seed phrase (only ${te.length} of ${e.length} words)`),children:[H(U,{name:`copy`}),` Copy phrase`]}),H(`span`,{class:`muted small helper`,children:[`Tip: paste a whole phrase into word 1.`,Mt()?` Phrases in other scripts (Japanese, Chinese…) can only be pasted on phones.`:``]})]}),H(`ol`,{class:`word-grid`,"aria-label":`Seed words`,children:e.map((t,r)=>{let a=k(r),o=n.includes(r)&&l!==r;return H(`li`,{class:`word ${o?`word-invalid`:``}`,children:[H(`span`,{class:`word-index`,"aria-hidden":`true`,children:r+1}),H(`input`,{ref:e=>{e&&!g.current.has(e)&&(g.current.add(e),e.type===`text`&&(e.type=`password`,e.type=`text`)),h.current[r]=e},class:`input mono`,...a?{type:`text`,list:_?`bip39-words`:void 0}:{type:`password`},value:t,"aria-label":`Word ${r+1}`,"aria-invalid":o,enterkeyhint:r===e.length-1?`done`:`next`,readOnly:i,onInput:e=>S(r,e),onPaste:e=>x(r,e),onKeyDown:e=>w(r,e),onFocus:()=>u(r),onBlur:T,oncompositionend:e=>C(r,e.currentTarget),...Nt})]},r)})}),re.length>0&&H(`p`,{class:`hint`,role:`status`,children:[`Not in the wordlist. Did you mean:`,` `,re.map(e=>H(`button`,{type:`button`,class:`link-button`,onMouseDown:e=>e.preventDefault(),onClick:()=>E(l,e),children:e},e)),`?`]}),O&&!i&&H(`p`,{class:`hint`,children:[H(`button`,{type:`button`,class:`button small`,onClick:ee,children:`Expand abbreviated words`}),` `,H(`span`,{class:`muted small`,children:`Only for English BIP39 phrases.`})]}),p&&H(`p`,{class:`hint`,role:`status`,children:p})]})},hn=Object.fromEntries(Object.entries(J).map(([e,t])=>[e,t.label])),gn={mnemonic:`Seed phrases`,privateKey:`Wallet keys`,sshKey:`SSH keys`,pgpKey:`PGP keys`,apiKey:`API keys and tokens`,genericKey:`Other keys`,recoveryCodes:`Recovery codes`,other:`Other secrets`},_n={mnemonic:`seed`,privateKey:`wallet`,sshKey:`terminal`,pgpKey:`mail`,apiKey:`code`,genericKey:`key`,recoveryCodes:`list`,other:`lock`},vn=[[`none`,`No grouping`],[`kind`,`Type`],[`chain`,`Chain or service`],[`wallet`,`Wallet or account`],[`tag`,`First tag`]],yn=e=>`Untitled ${/^[A-Z][A-Z]/.test(e)?e:e.toLowerCase()}`,bn=e=>{let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleDateString(void 0,{year:`numeric`,month:`long`,day:`numeric`})},xn=new Map([...`123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz`].map((e,t)=>[e,BigInt(t)])),Sn=e=>{let t=0n;for(let n of e){let e=xn.get(n);if(e===void 0)return null;t=t*58n+e}let n=[];for(;t>0n;)n.unshift(Number(t%256n)),t/=256n;let r=0;for(;r{let t=Sn(e);if(!t||t.length<5)return null;let n=t.slice(0,-4);return Ke((await We(await We(n))).slice(0,4),t.slice(-4))?n:null},wn=`qpzry9x8gf2tvdw0s3jn54khce6mua7l`,Tn=1,En=734539939,Dn=e=>{let t=[996825010,642813549,513874426,1027748829,705979059],n=1;for(let r of e){let e=n>>>25;n=(n&33554431)<<5^r;for(let r=0;r<5;r++)e>>>r&1&&(n^=t[r])}return n>>>0},On=e=>[...[...e].map(e=>e.charCodeAt(0)>>5),0,...[...e].map(e=>e.charCodeAt(0)&31)],kn=/^(nsec|npub|bc|tb|ltc|age|age-secret-key-)$|_x?[sv]k$|xprv|xpub|^addr|^stake/,An=e=>{if(e!==e.toLowerCase()&&e!==e.toUpperCase())return null;let t=e.toLowerCase(),n=t.lastIndexOf(`1`);if(n<1||n+7>t.length)return null;let r=t.slice(0,n),i=[];for(let e of t.slice(n+1)){let t=wn.indexOf(e);if(t===-1)return null;i.push(t)}let a=Dn([...On(r),...i]),o=a===Tn?`bech32`:a===En?`bech32m`:null;return o?{hrp:r,variant:o,words:i.slice(0,-6)}:null},jn=e=>{let t=0,n=0,r=[];for(let i of e)for(t=t<<5|i,n+=5;n>=8;)n-=8,r.push(t>>n&255);return n>=5||t&(1<Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``),Fn=e=>{let t;try{t=JSON.parse(e)}catch{return null}if(Array.isArray(t)&&t.length===0)return{level:`info`,label:`Empty list`};if(Array.isArray(t)&&t.every(e=>Number.isInteger(e)&&e>=0&&e<=255))return t.length===64?{level:`ok`,label:`Byte array, 64 bytes`,detail:`Solana CLI keypair file format.`}:{level:`info`,label:`Byte array, ${t.length} bytes`};if(t&&typeof t==`object`){let e=t;if(e.crypto&&Number(e.version)===4&&typeof e.pubkey==`string`)return{level:`ok`,label:`Encrypted keystore (EIP-2335, Ethereum validator)`,detail:`Store its password in the keystore password field.`};if((e.crypto||e.Crypto)&&Number(e.version)===3)return{level:`ok`,label:`Encrypted keystore (Web3 Secret Storage v3)`,detail:`Store its password in the keystore password field.`};if(e.type===`service_account`&&typeof e.private_key==`string`)return{level:`ok`,label:`Google Cloud service account key`,detail:`JSON key file with a private key.`};let n=Array.isArray(e.keys)?e.keys.filter(e=>e&&typeof e==`object`):[e],r=n.find(e=>`d`in e||`k`in e)??n[0];return r&&typeof r.kty==`string`?`d`in r||`k`in r?{level:`ok`,label:`JSON Web Key (${r.kty}, private)`}:{level:`warn`,label:`JSON Web Key (${r.kty}, public)`,detail:Q}:{level:`info`,label:`JSON document`}}return null},In={"ssh-ed25519":`Ed25519`,"ssh-rsa":`RSA`,"ssh-dss":`DSA`,"ecdsa-sha2-nistp256":`ECDSA P-256`,"ecdsa-sha2-nistp384":`ECDSA P-384`,"ecdsa-sha2-nistp521":`ECDSA P-521`,"sk-ssh-ed25519@openssh.com":`Ed25519 security key`,"sk-ecdsa-sha2-nistp256@openssh.com":`ECDSA security key`},Ln=e=>{let t;try{t=He(e.replace(/\s+/g,``))}catch{return null}if(Re(t.slice(0,15))!==`openssh-key-v1\0`)return null;let n=15,r=new DataView(t.buffer,t.byteOffset,t.byteLength),i=()=>{if(n+4>t.length)throw Error(`truncated`);let e=r.getUint32(n);if(n+=4,n+e>t.length)throw Error(`truncated`);let i=t.slice(n,n+e);return n+=e,i};try{let e=Re(i());i(),i(),n+=4;let t=i(),r=i(),a=new DataView(t.buffer,t.byteOffset).getUint32(0),o=Re(t.slice(4,4+a)),s=e!==`none`;if(!s){let e=new DataView(r.buffer,r.byteOffset,r.byteLength);if(r.length<8||e.getUint32(0)!==e.getUint32(4))return null}return{keyType:o,encrypted:s}}catch{return null}},Rn=e=>{let t=11994318;for(let n of e){t^=n<<16;for(let e=0;e<8;e++)t<<=1,t&16777216&&(t^=25578747)}return t&16777215},zn=e=>{let t=e.split(/\r?\n/).map(e=>e.trim()),n=t.indexOf(``),r=t.slice(n===-1?1:n+1).filter(e=>e&&!e.startsWith(`-----`)),i=r.findIndex(e=>/^=[A-Za-z0-9+/]{4}$/.test(e));if(i===-1)return null;try{let e=He(r.slice(0,i).join(``)),t=He(r[i].slice(1));return Rn(e)===(t[0]<<16|t[1]<<8|t[2])}catch{return!1}},Bn={"PUBLIC KEY":`PEM public key`,"RSA PUBLIC KEY":`PEM RSA public key`,CERTIFICATE:`Certificate`,"PGP PUBLIC KEY BLOCK":`PGP public key block`},Vn={"PGP MESSAGE":`PGP message`,"PGP SIGNATURE":`PGP signature`,"PGP SIGNED MESSAGE":`PGP signed message`},Hn=e=>{if(e.includes(`:`))return null;let t;try{t=He(e.replace(/\s+/g,``))}catch{return!1}if(t.length<2||t[0]!==48)return!1;let n=t[1],r=2;if(n&128){let e=n&127;if(e<1||e>4||t.length<2+e)return!1;n=0;for(let r=0;r{let r=/Proc-Type:\s*4,ENCRYPTED/i.test(t);if(Vn[e])return{level:`warn`,label:Vn[e],detail:`This is not a key.`};if(Bn[e])return{level:`warn`,label:Bn[e],detail:Q};if(/PRIVATE KEY$/.test(e)&&e!==`OPENSSH PRIVATE KEY`&&Hn(t)===!1)return{level:`error`,label:`Private key block is damaged or incomplete`,detail:`A line may be missing or changed.`};switch(e){case`OPENSSH PRIVATE KEY`:{let e=Ln(t);return e?{level:`ok`,label:`OpenSSH private key (${In[e.keyType]??e.keyType})`,detail:e.encrypted?`Protected by a passphrase.`:`Not passphrase-protected.`}:{level:`error`,label:`OpenSSH private key, but it could not be read`,detail:`Check that it was copied completely.`}}case`PGP PRIVATE KEY BLOCK`:{let e=zn(n);return e===!1?{level:`error`,label:`PGP private key, but the checksum fails`,detail:`Check for a typo or missing line.`}:{level:`ok`,label:`PGP private key block`,detail:e?`Checksum OK.`:void 0}}case`RSA PRIVATE KEY`:return{level:`ok`,label:`PEM RSA private key (PKCS#1)`,detail:r?`Protected by a passphrase.`:void 0};case`EC PRIVATE KEY`:return{level:`ok`,label:`PEM EC private key (SEC1)`,detail:r?`Protected by a passphrase.`:void 0};case`DSA PRIVATE KEY`:return{level:`ok`,label:`PEM DSA private key`,detail:r?`Protected by a passphrase.`:void 0};case`PRIVATE KEY`:return{level:`ok`,label:`PEM private key (PKCS#8)`};case`ENCRYPTED PRIVATE KEY`:return{level:`ok`,label:`PEM private key (PKCS#8)`,detail:`Protected by a passphrase.`};default:return{level:`info`,label:`PEM block (${e.toLowerCase()})`}}},Wn=e=>/PRIVATE KEY/.test(e),Gn=e=>{let t=[...e.matchAll(/-----BEGIN ([A-Z0-9 ]+)-----([\s\S]*?)-----END \1-----/g)],n=(e.match(/-----BEGIN [A-Z0-9 ]+-----/g)??[]).length,r={level:`error`,label:`Key block is incomplete`,detail:`The matching -----END ...----- line is missing.`},i=t.find(e=>Wn(e[1]));if(i)return Un(i[1],i[2],i[0]);let a=/-----BEGIN (PGP MESSAGE|PGP SIGNATURE|PGP SIGNED MESSAGE)-----/.exec(e);if(a)return{level:`warn`,label:Vn[a[1]],detail:`This is not a key.`};if(n>t.length)return r;if(!t.length)return null;let o=t.map(e=>Un(e[1],e[2],e[0]));return o.find(e=>e.level===`warn`)??o[0]},Kn=[{pattern:/^gh[pousr]_[A-Za-z0-9]{36,}$/,label:`GitHub token`},{pattern:/^github_pat_\w{50,}$/,label:`GitHub fine-grained token`},{pattern:/^glpat-[\w-]{20,}$/,label:`GitLab access token`},{pattern:/^npm_[A-Za-z0-9]{36}$/,label:`npm access token`},{pattern:/^(sk|rk)_(live|test)_[A-Za-z0-9]{16,}$/,label:`Stripe secret key`},{pattern:/^pk_(live|test)_[A-Za-z0-9]{16,}$/,label:`Stripe publishable key`,level:`warn`,detail:Q},{pattern:/^xox[abposr]-[A-Za-z0-9-]{10,}$/,label:`Slack token`},{pattern:/^AIza[\w-]{35}$/,label:`Google API key`},{pattern:/^(AKIA|ASIA)[0-9A-Z]{16}$/,label:`AWS access key ID`,level:`info`,detail:`The 40-character secret access key is a separate value; store it as well.`},{pattern:/^SG\.[\w-]{22}\.[\w-]{43}$/,label:`SendGrid API key`},{pattern:/^dop_v1_[a-f0-9]{64}$/,label:`DigitalOcean token`},{pattern:/^sk-[\w-]{20,}$/,label:`API secret key (sk-…)`},{pattern:/^eyJ[\w-]+\.eyJ[\w-]+\.[\w-]*$/,label:`JSON Web Token`,level:`info`,detail:`Tokens like this usually expire.`}],qn=async e=>{let t=e.trim();if(!t)return null;if(/^\[[\w .-]+\][ \t]*\r?$/.test(t.split(` +`)[0])&&/^[ \t]*[\w.-]+[ \t]*=/m.test(t))return/aws_secret_access_key\s*=/i.test(t)?{level:`ok`,label:`AWS credentials file`,detail:`Contains a secret access key.`}:{level:`info`,label:`Settings file (INI)`};let n=/^\[([0-9a-fA-F]{8}(?:\/\d+['hH]?)*)\]\s*(?=\S)/.exec(t);if(n){let e=await qn(t.slice(n[0].length));if(e)return{...e,detail:[e.detail,`Key origin [${n[1]}].`].filter(Boolean).join(` `)}}if(t.startsWith(`{`)||t.startsWith(`[`))return Fn(t)??{level:`warn`,label:`Looks like JSON, but it does not parse.`};let r=/^AGE-SECRET-KEY-1[0-9A-Z]+$/m.exec(t);if(r&&t.includes(` +`))return qn(r[0]);if(/^---- BEGIN SSH2 PUBLIC KEY ----/m.test(t))return{level:`warn`,label:`SSH public key (SSH2 format)`,detail:Q};let i=Gn(t);if(i)return i;let a=/^PuTTY-User-Key-File-\d+:\s*(\S+)/.exec(t);if(a){let e=/^Private-Lines:\s*(\d+)\s*$/m.exec(t);if(e&&(t.slice(e.index+e[0].length).split(` +`).map(e=>e.trim()).filter(e=>e&&!/^Private-MAC:/.test(e)).filter(e=>/^[A-Za-z0-9+/=]+$/.test(e)).lengthe.pattern.test(t));if(s)return{level:s.level??`ok`,label:s.label,detail:s.detail};let c=Xt(t);if(c.length>=12&&c.length<=48&&c.every(Gt))return{level:`warn`,label:`Looks like a ${c.length}-word seed phrase`,detail:`Use a "Seed phrase" entry to get word-by-word checks.`};if(/^(0x)?[0-9a-fA-F]+$/i.test(t)&&t.replace(/^0x/i,``).length%2==0){let e=Be(t.replace(/^0X/,`0x`)),n=/^0x/i.test(t);return e.length===32?{level:`ok`,label:`Hex, 32 bytes${n?` (0x-prefixed)`:``}`,detail:`Raw 256-bit private key (Ethereum/EVM, Bitcoin, Cosmos and others).`}:e.length===20?{level:`warn`,label:`Hex, 20 bytes`,detail:Q+` (EVM address length)`}:e.length===33||e.length===65?{level:`warn`,label:`Hex, ${e.length} bytes`,detail:Q+` (public key length)`}:{level:`info`,label:`Hex, ${e.length} bytes`}}let l=An(t);if(l){let e=l.variant===`bech32`?jn(l.words):null;switch(l.hrp){case`age-secret-key-`:return e?.length===32?{level:`ok`,label:`age secret key`,detail:`Checksum OK.`}:{level:`error`,label:`age secret key with unexpected length`,detail:`Check that it was copied completely.`};case`age`:return{level:`warn`,label:`age recipient (public key)`,detail:Q};case`nsec`:return e?.length===32?{level:`ok`,label:`Nostr private key (nsec)`,detail:`Checksum OK.`}:{level:`error`,label:`nsec with unexpected length`};case`npub`:return{level:`warn`,label:`Nostr public key (npub)`,detail:Q};case`bc`:case`tb`:case`ltc`:return{level:`warn`,label:`Address (bech32)`,detail:Q};default:return/_x?sk$/.test(l.hrp)||l.hrp.includes(`xprv`)?{level:`ok`,label:`Bech32 secret key (${l.hrp})`,detail:`Checksum OK.`}:/_x?vk$/.test(l.hrp)||l.hrp.includes(`xpub`)||l.hrp.startsWith(`addr`)||l.hrp.startsWith(`stake`)?{level:`warn`,label:`Bech32 (${l.hrp})`,detail:Q}:{level:`info`,label:`Bech32 data (${l.hrp})`,detail:`Checksum OK.`}}}{let e=t.toLowerCase(),n=/^([a-z0-9_-]+)1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]{6,}$/.exec(e);if(n&&(t===e||t===t.toUpperCase())&&kn.test(n[1]))return{level:`error`,label:`Bech32 checksum fails`,detail:`Check for a typo.`}}if(/^[A-Za-z0-9+/]+={0,2}$/.test(t)&&t.length%4==0&&/[+/=]/.test(t))try{let e=He(t);return e.length===32?{level:`ok`,label:`Base64, 32 bytes`,detail:`The format of WireGuard keys and many other 256-bit keys.`}:{level:`info`,label:`Base64, ${e.length} bytes`}}catch{}if(t.length<=200&&/^[1-9A-HJ-NP-Za-km-z]+$/.test(t)){if(Ue()){let e=await Cn(t);if(e){if(e.length===78){let t=Mn[Pn(e.slice(0,4))];return t?t.private?{level:`ok`,label:`Extended private key (${t.name})`,detail:`${t.note}. Checksum OK.`}:{level:`warn`,label:`Extended public key (${t.name})`,detail:Q}:{level:`info`,label:`Extended key (unknown version)`,detail:`Checksum OK.`}}let t=Nn[e[0]];return t&&(e.length===33||e.length===34&&e[33]===1)?{level:`ok`,label:`WIF private key (${t}, ${e.length===34?`compressed`:`uncompressed`})`,detail:`Checksum OK.`}:e.length===21?{level:`warn`,label:`Address (Base58Check)`,detail:Q}:{level:`info`,label:`Base58Check, ${e.length} bytes`,detail:`Checksum OK.`}}let n=Sn(t);if(n&&(n.length===37||n.length===38)&&Nn[n[0]])return{level:`error`,label:`Looks like WIF, but the checksum fails`,detail:`Check for a typo.`};if(/^(?:[xyztuvYZUV](?:prv|pub)|[LM]t(?:pv|ub)|dg(?:pv|ub))/.test(t)){if(t.length===111)return{level:`error`,label:`Looks like an extended key, but the checksum fails`,detail:`Check for a typo.`};if(t.length===110||t.length===112)return{level:`error`,label:`Looks like an extended key, but a character may be missing or extra`,detail:`Extended keys are 111 characters.`}}}let e=Sn(t);if(e?.length===64)return{level:`ok`,label:`Base58, 64 bytes`,detail:`Solana-style keypair (Phantom/Solflare export).`};if(e?.length===32)return{level:`info`,label:`Base58, 32 bytes`,detail:`Could be an ed25519 secret seed, or a Solana address.`};if(e)return{level:`info`,label:`Base58, ${e.length} bytes`}}return{level:`info`,label:`Unrecognized format`,detail:`Stored as typed.`}},Jn=async e=>{let t=e.trim();if(!t)return null;if(/-----BEGIN [A-Z0-9 ]*PRIVATE KEY[A-Z0-9 ]*-----/.test(t))return`a private key block`;let n=t.split(/[\s,;()[\]]+/).map(e=>e.split(`/`)[0]).filter(e=>e.length>=40);for(let e of[t,...n]){let t=await qn(e);if(t?.level===`ok`&&!/^(Hex|Base64)/.test(t.label))return t.label}return null},Yn=`Bitcoin.Ethereum.Solana.Cardano.Monero.Litecoin.Dogecoin.Polkadot.Cosmos.Avalanche.Polygon.BNB Chain.Arbitrum.Base.Optimism.Tron.XRP Ledger.Tezos.Algorand.Stellar.Near.Sui.Aptos.Lightning (LND).Nostr.Multi-chain`.split(`.`),Xn=[`Ledger`,`Trezor`,`Coldcard`,`BitBox02`,`Keystone`,`Blockstream Jade`,`Foundation Passport`,`Sparrow`,`Electrum`,`Nunchuk`,`BlueWallet`,`Phoenix`,`MetaMask`,`Rabby`,`Rainbow`,`Phantom`,`Solflare`,`Exodus`,`Trust Wallet`,`Coinbase Wallet`,`Cake Wallet`,`Feather`,`Monero GUI`],Zn=[`GitHub`,`GitLab`,`Bitbucket`,`AWS`,`Google Cloud`,`Azure`,`Cloudflare`,`DigitalOcean`,`Vercel`,`Stripe`,`Slack`,`npm`,`Docker Hub`,`Apple ID`,`Google account`,`Microsoft account`,`Proton`,`Standard Notes`,`Coinbase`,`Kraken`,`Binance`,`Gemini`,`Bitstamp`],Qn=[[`m/44'/0'/0'`,`BTC legacy (BIP44)`],[`m/49'/0'/0'`,`BTC nested SegWit (BIP49)`],[`m/84'/0'/0'`,`BTC native SegWit (BIP84)`],[`m/86'/0'/0'`,`BTC Taproot (BIP86)`],[`m/48'/0'/0'/2'`,`BTC multisig (BIP48)`],[`m/44'/60'/0'/0/0`,`Ethereum / EVM`],[`m/44'/501'/0'/0'`,`Solana`],[`m/1852'/1815'/0'`,`Cardano`],[`m/44'/118'/0'/0/0`,`Cosmos`]],$n=()=>H(C,{children:[H(`datalist`,{id:`chains`,children:Yn.map(e=>H(`option`,{value:e}))}),H(`datalist`,{id:`wallets`,children:Xn.map(e=>H(`option`,{value:e}))}),H(`datalist`,{id:`services`,children:Zn.map(e=>H(`option`,{value:e}))}),H(`datalist`,{id:`paths`,children:Qn.map(([e,t])=>H(`option`,{value:e,label:t}))})]}),er=(e,t,n=`${t}s`)=>`${e} ${e===1?t:n}`,$=({label:e,hint:t,children:n,wide:r,safety:i})=>H(`div`,{class:`field ${r?`field-wide`:``}`,children:[H(`label`,{class:`field-control`,children:[H(`span`,{class:`field-label`,children:e}),n]}),t&&H(`span`,{class:`hint ${i?`hint-safety`:``}`,children:t})]}),tr=({id:e,title:t,icon:n,summary:r,defaultOpen:i,action:a,children:o})=>{let[s]=z(i),[c,l]=Ot(e,s),u=`section-${e.replace(/[^a-z0-9]/gi,`-`)}`;return H(`section`,{class:`section ${c?`open`:`closed`}`,children:[H(`header`,{class:`section-header`,children:[H(`h3`,{class:`section-heading`,children:H(`button`,{type:`button`,class:`section-toggle`,"aria-expanded":c,"aria-controls":u,onClick:()=>l(!c),children:[H(U,{name:`chevron`,size:14,class:`chevron`}),n&&H(U,{name:n}),H(`span`,{children:t}),!c&&r&&H(`span`,{class:`section-summary`,children:r})]})}),a&&H(`button`,{type:`button`,class:`button small`,onClick:()=>{a.onClick(),l(!0)},children:[H(U,{name:`plus`}),` `,a.label]})]}),c&&H(`div`,{class:`section-body`,id:u,children:o})]})},nr={valid:`ok`,invalid:`error`,incomplete:`info`,unchecked:`info`},rr=({entry:e,update:t,showLabel:n,focusLabel:r})=>{let{readOnly:i}=Z(),a=V(null);B(()=>{r&&a.current?.focus()},[]);let o=J[e.kind],s=Xe(e.kind),c=Tt(e),l=[e.description&&`description`,e.createdOn&&`created ${e.createdOn}`,e.expiresOn&&o.expires&&`expires ${e.expiresOn}`].filter(Boolean).join(` · `);return H(tr,{id:`${e.id}:details`,title:`Details`,summary:l||`empty`,defaultOpen:!e.label,children:[n&&H($,{label:`Label`,wide:!0,children:H(`input`,{ref:a,class:`input`,value:e.label,placeholder:yn(hn[e.kind]),readOnly:i,onInput:e=>t({label:e.currentTarget.value})})}),H($,{label:`Description`,wide:!0,children:H(`textarea`,{class:`input`,rows:2,value:e.description,placeholder:`What is this wallet or key for?`,readOnly:i,onInput:e=>t({description:e.currentTarget.value}),...Nt,"data-secret":void 0})}),sr(e,e.description)&&H(`p`,{class:`status status-error`,role:`status`,children:[H(U,{name:`alert`}),` This text repeats the entry's secret, and it is not hidden.`]}),H(`div`,{class:`row`,children:[s?H(C,{children:[H($,{label:o.serviceLabel,children:H(`input`,{class:`input`,list:`chains`,value:e.chain,readOnly:i,onInput:e=>t({chain:e.currentTarget.value})})}),H($,{label:o.accountLabel,children:H(`input`,{class:`input`,list:`wallets`,value:e.wallet,readOnly:i,onInput:e=>t({wallet:e.currentTarget.value})})})]}):H(C,{children:[H($,{label:o.serviceLabel,children:H(`input`,{class:`input`,list:`services`,value:e.service,readOnly:i,onInput:e=>t({service:e.currentTarget.value})})}),H($,{label:o.accountLabel,children:H(`input`,{class:`input`,value:e.account,readOnly:i,onInput:e=>t({account:e.currentTarget.value}),...Pt})})]}),H($,{label:`Date created`,children:H(`input`,{class:`input`,type:`date`,value:e.createdOn,readOnly:i,onInput:e=>t({createdOn:e.currentTarget.value})})}),o.expires&&H($,{label:`Expires on`,hint:c===null?`Optional. You are warned 30 days ahead.`:void 0,children:H(`input`,{class:`input`,type:`date`,value:e.expiresOn,readOnly:i,onInput:e=>t({expiresOn:e.currentTarget.value})})})]}),c!==null&&c<=30&&H(`p`,{class:`status ${c<0?`status-error`:`status-warn`}`,children:[H(U,{name:`clock`}),` `,c<0?`Expired on ${e.expiresOn}.`:c===0?`Expires today.`:`Expires in ${c} day${c===1?``:`s`}.`]}),H($,{label:`Tags`,hint:`Comma separated.`,wide:!0,children:H(xr,{tags:e.tags,onChange:e=>t({tags:e})})})]})},ir=({entry:e,update:t})=>{let{readOnly:n,confirm:r,toast:i}=Z(),a=V(e);a.current=e;let o=At(()=>rn(e.scheme,e.words),[e.scheme,e.words.join(` `)]),s=zt.find(t=>t.id===e.scheme),c=[...new Set([...s.counts,...Bt])].sort((e,t)=>e-t),l=e.words.filter(Boolean).length,[u,d]=z(!1),f=async n=>{if(!Number.isInteger(n)||n<1||n>48||n===e.words.length)return!1;let o=e.words,s=o.slice(n).filter(Boolean).length;if(s>0){if(!await r({title:`Remove words?`,message:`Shrinking to ${n} words removes ${s} word${s===1?``:`s`} you entered.`,confirmLabel:`Remove`,danger:!0}))return!1;if(a.current.words.join(` +`)!==o.join(` +`))return i(`The words changed while this was open. Nothing was removed.`,`error`),!1}return t({words:Array.from({length:n},(e,t)=>o[t]??``)}),!0},p=n=>{let r=zt.find(e=>e.id===n);l===0&&r.counts.length&&!r.counts.includes(e.words.length)?t({scheme:n,words:Array(r.counts[0]).fill(``)}):t({scheme:n})},m=`${s.label} · ${l===e.words.length?er(l,`word`):`${l} of ${e.words.length} words`}${e.passphrase?` + passphrase`:``}`;return H(tr,{id:`${e.id}:seed`,title:`Seed phrase`,icon:`seed`,summary:m,defaultOpen:!0,children:[H(`div`,{class:`row`,children:[H($,{label:`Scheme`,children:H(`select`,{class:`input`,value:e.scheme,disabled:n,onChange:e=>p(e.currentTarget.value),children:zt.map(e=>H(`option`,{value:e.id,children:e.label}))})}),H($,{label:`Words`,children:H(`select`,{class:`input`,value:u||!c.includes(e.words.length)?`custom`:String(e.words.length),disabled:n,onChange:async t=>{let n=t.currentTarget,r=n.value;r===`custom`?d(!0):(d(!1),await f(Number(r))||(n.value=c.includes(e.words.length)?String(e.words.length):`custom`))},children:[c.map(e=>H(`option`,{value:String(e),children:[e,s.counts.includes(e)?``:` (non-standard)`]})),H(`option`,{value:`custom`,children:`Custom…`})]})}),(u||!c.includes(e.words.length))&&H($,{label:`Custom count`,children:H(`input`,{class:`input`,type:`number`,min:1,max:48,value:e.words.length,readOnly:n,onChange:e=>f(Number(e.currentTarget.value))})})]}),H(mn,{words:e.words,scheme:e.scheme,unknownWords:o?.unknownWords??[],onChange:e=>t({words:e})}),o&&H(`p`,{class:`status status-${nr[o.status]}`,role:`status`,children:[H(U,{name:o.status===`valid`?`check`:o.status===`invalid`?`alert`:`shield`}),` `,o.message]}),H(cr,{entry:e,update:t})]})},ar=e=>setTimeout(()=>document.querySelector(`[data-row="${e}"] input`)?.focus()),or=e=>e.passphrase.length>=4&&e.passphraseHint.toLowerCase().includes(e.passphrase.toLowerCase()),sr=(e,t)=>{let n=t.toLowerCase();if(!n)return!1;if(e.secret.trim().length>=12&&n.includes(e.secret.trim().toLowerCase()))return!0;let r=e.words.filter(Boolean).map(e=>e.toLowerCase().replace(/[.*+?^${}()|[\]\\]/g,`\\$&`));for(let e=0;e+4<=r.length;e++)if(RegExp(`\\b${r.slice(e,e+4).join(`\\s+`)}\\b`).test(n))return!0;return!1},cr=({entry:e,update:t})=>{let{readOnly:n}=Z(),r=J[e.kind];return r.passphraseLabel?H(`div`,{class:`row`,children:[H($,{label:r.passphraseLabel,hint:r.passphraseHint,safety:!0,children:H(Ft,{label:r.passphraseLabel,value:e.passphrase,onInput:e=>t({passphrase:e}),placeholder:`None`})}),H($,{label:`Passphrase hint`,hint:`Not hidden. Never write the passphrase itself here.`,safety:!0,children:H(`input`,{class:`input`,value:e.passphraseHint,readOnly:n,onInput:e=>t({passphraseHint:e.currentTarget.value}),...Pt})}),or(e)&&H(`p`,{class:`status status-error field-wide`,role:`status`,children:[H(U,{name:`alert`}),` The hint contains the passphrase. Anyone who opens this note can read it.`]})]}):null},lr={ok:`ok`,info:`info`,warn:`warn`,error:`error`},ur=({entry:e,update:t})=>{let n=J[e.kind],r=At(()=>qn(e.secret),[e.secret]);return H(tr,{id:`${e.id}:key`,title:n.secretLabel,icon:`key`,summary:e.secret?r?.label??`set`:`empty`,defaultOpen:!0,children:[H($,{label:n.secretLabel,wide:!0,children:H(Ft,{label:n.secretLabel,value:e.secret,onInput:e=>t({secret:e}),placeholder:n.secretPlaceholder,multiline:n.secret===`key`&&(e.kind!==`privateKey`||e.secret.includes(` +`)),onMultilinePaste:e=>t({secret:e}),mono:!0})}),H(`p`,{class:`status ${r?`status-${lr[r.level]}`:``}`,role:`status`,children:r&&H(C,{children:[H(U,{name:r.level===`ok`?`check`:r.level===`info`?`shield`:`alert`}),` `,r.label,r.detail&&H(`span`,{class:`muted`,children:[` · `,r.detail]})]})}),H(cr,{entry:e,update:t})]})},dr=({entry:e,update:t})=>{let n=e.secret.split(/\n/).filter(e=>e.trim()).length;return H(tr,{id:`${e.id}:codes`,title:`Recovery codes`,icon:`list`,summary:n?`${n} code${n===1?``:`s`}`:`empty`,defaultOpen:!0,children:H($,{label:`Codes`,hint:`One per line. Delete or mark a code once used.`,wide:!0,children:H(Ft,{label:`Recovery codes`,value:e.secret,onInput:e=>t({secret:e}),placeholder:`One code per line`,multiline:!0,mono:!0})})})},fr=({text:e})=>{let t=At(()=>Jn(e),[e]);return t?H(`p`,{class:`status status-error`,role:`status`,children:[H(U,{name:`alert`}),` This looks like private key material (`,t,`). This field is not hidden: move it to the secret field.`]}):null},pr=(e,t)=>{let n=e.trim();return t&&(n=n.replace(/^\[([0-9a-fA-F]{8})[^\]]*\].*$/,`$1`).replace(/^0x/i,``).replace(/\s+/g,``)),n},mr=e=>e.trim().replace(/[’‘′`]/g,`'`).replace(/^M\//,`m/`),hr=({entry:e,update:t})=>{let{readOnly:n}=Z(),r=J[e.kind].publicKey;if(!r)return null;let i=At(()=>Jn(e.fingerprint),[e.fingerprint]),a=[e.publicInfo&&`public key`,e.fingerprint&&(i?`fingerprint`:e.fingerprint)].filter(Boolean).join(` · `),o=e.kind===`pgpKey`&&e.fingerprint&&!/^([0-9a-fA-F]{40}|[0-9a-fA-F]{64})$/.test(e.fingerprint.replace(/\s/g,``));return H(tr,{id:`${e.id}:public`,title:`Public info`,icon:`eye`,summary:a||`empty`,defaultOpen:!1,children:[H(`p`,{class:`muted small helper`,children:`Not secret. Lets you match this entry to a server, keyring or recipient.`}),H($,{label:r.label,wide:!0,children:H(`textarea`,{class:`input mono`,rows:e.publicInfo?3:2,value:e.publicInfo,placeholder:r.placeholder,readOnly:n,onInput:e=>t({publicInfo:e.currentTarget.value}),...Pt})}),H(fr,{text:e.publicInfo}),H($,{label:r.fingerprintLabel,wide:!0,children:H(`input`,{class:`input mono`,value:e.fingerprint,placeholder:r.fingerprintPlaceholder,readOnly:n,onInput:e=>t({fingerprint:e.currentTarget.value}),onBlur:n=>{let r=pr(n.currentTarget.value,!1);r!==e.fingerprint&&t({fingerprint:r})},...Pt})}),H(fr,{text:e.fingerprint}),o&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` PGP fingerprints are 40 hex characters (64 for newer v6 keys).`]})]})},gr=({entry:e,update:t})=>{let{readOnly:n}=Z(),r=!!(e.derivationPath||e.fingerprint||e.publicInfo),i=At(()=>Jn(e.fingerprint),[e.fingerprint]),a=[e.derivationPath,e.fingerprint&&(i?`fingerprint`:e.fingerprint),e.publicInfo&&`addresses`].filter(Boolean).join(` · `),o=e.derivationPath.trim();return H(tr,{id:`${e.id}:public`,title:`Public info`,icon:`eye`,summary:a||`empty`,defaultOpen:!1,children:[H(`p`,{class:`muted small helper`,children:`Not secret. Helps you recognize the wallet without revealing the secret.`}),H(`div`,{class:`row`,children:[H($,{label:`Derivation path`,children:H(`input`,{class:`input mono`,list:`paths`,value:e.derivationPath,placeholder:`m/84'/0'/0'`,readOnly:n,onInput:e=>t({derivationPath:e.currentTarget.value}),onBlur:n=>{let r=mr(n.currentTarget.value);r!==e.derivationPath&&t({derivationPath:r})},...Pt})}),H($,{label:`Master fingerprint`,children:H(`input`,{class:`input mono`,value:e.fingerprint,placeholder:`e.g. 73c5da0a`,readOnly:n,onInput:e=>t({fingerprint:e.currentTarget.value}),onBlur:n=>{let r=pr(n.currentTarget.value,!0);r!==e.fingerprint&&t({fingerprint:r})},...Pt})})]}),o&&!/^m(\/\d+['hH]?)*$/.test(o)&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` `,/[’‘′`]/.test(o)?`Use straight apostrophes (') in derivation paths; curly ones are fixed when you leave the field.`:`Derivation paths look like m/84'/0'/0'.`]}),e.fingerprint&&!i&&!/^[0-9a-fA-F]{8}$/.test(e.fingerprint.trim())&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` A master fingerprint is 8 hex characters.`]}),H($,{label:`Addresses / xpub`,wide:!0,children:H(`textarea`,{class:`input mono`,rows:r?3:2,value:e.publicInfo,placeholder:`First receive address, xpub/zpub…`,readOnly:n,onInput:e=>t({publicInfo:e.currentTarget.value}),...Pt})}),H(fr,{text:e.publicInfo}),H(fr,{text:e.fingerprint})]})},_r=({entry:e,update:t,reminderMonths:n})=>{let{readOnly:r}=Z(),i=(n,r)=>t({backups:e.backups.map(e=>e.id===n?{...e,...r}:e)}),a=wt(e,n),o=Ct(e),s=H(`span`,{class:a?`status-warn`:void 0,children:[e.backups.length?er(e.backups.length,`location`):`none recorded`,o?` · checked ${o}`:``,a?` · check due`:``]});return H(tr,{id:`${e.id}:backups`,title:`Backups`,icon:`shield`,summary:s,defaultOpen:!1,action:r?void 0:{label:`Add location`,onClick:()=>{let n=qe();t({backups:[...e.backups,{id:n,location:``,verifiedOn:``}]}),ar(n)}},children:[H(`p`,{class:`status ${a?`status-warn`:`status-info`}`,children:[H(U,{name:a?`alert`:`check`}),` `,o?`Last checked ${o}.`:`No backup check recorded.`,a&&n>0&&` Check your backups at least every ${n} months.`]}),e.backups.length===0&&H(`p`,{class:`muted small helper`,children:`Record where copies are kept, like "steel plate in home safe". Do not record the secret itself here.`}),e.backups.map(n=>H(`div`,{class:`row backup-row`,"data-row":n.id,children:[H(`input`,{class:`input grow`,value:n.location,placeholder:`Location, e.g. steel plate in safe`,"aria-label":`Backup location`,readOnly:r,onInput:e=>i(n.id,{location:e.currentTarget.value}),...Pt}),H(`input`,{class:`input`,type:`date`,value:n.verifiedOn,"aria-label":`Last checked`,readOnly:r,onInput:e=>i(n.id,{verifiedOn:e.currentTarget.value})}),!r&&H(C,{children:[H(`button`,{type:`button`,class:`button small`,onClick:()=>i(n.id,{verifiedOn:nt()}),children:`Checked today`}),H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Remove backup location`,title:`Remove`,onClick:()=>t({backups:e.backups.filter(e=>e.id!==n.id)}),children:H(U,{name:`x`})})]})]},n.id))]})},vr=({entry:e,update:t})=>{let{readOnly:n}=Z(),r=(n,r)=>t({customFields:e.customFields.map(e=>e.id===n?{...e,...r}:e)}),i=J[e.kind].secret===`fields`;return H(tr,{id:`${e.id}:fields`,title:i?`Fields`:`Extra fields`,icon:`plus`,summary:e.customFields.length?er(e.customFields.length,`field`):`none`,defaultOpen:i,action:n?void 0:{label:`Add field`,onClick:()=>{let n=qe();t({customFields:[...e.customFields,{id:n,label:``,value:``,hidden:!0}]}),ar(n)}},children:[e.customFields.length===0&&H(`p`,{class:`muted small helper`,children:`For PINs, keystore passwords, 2FA backup codes, multisig details or anything else.`}),e.customFields.map(i=>H(`div`,{class:`custom-field`,"data-row":i.id,children:[H(`input`,{class:`input custom-label`,value:i.label,placeholder:`Label`,"aria-label":`Field label`,readOnly:n,onInput:e=>r(i.id,{label:e.currentTarget.value})}),H(`div`,{class:`custom-value`,children:i.hidden?H(Ft,{label:i.label||`Field`,value:i.value,multiline:i.multiline,onInput:e=>r(i.id,{value:e}),onMultilinePaste:e=>r(i.id,{value:e,multiline:!0})}):i.multiline?H(`textarea`,{class:`input`,rows:3,value:i.value,"aria-label":i.label||`Field value`,readOnly:n,onInput:e=>r(i.id,{value:e.currentTarget.value}),...Pt}):H(`input`,{class:`input`,value:i.value,"aria-label":i.label||`Field value`,readOnly:n,onInput:e=>r(i.id,{value:e.currentTarget.value}),...Pt,onPaste:e=>{let t=e.clipboardData?.getData(`text`)??``;if(!/[\r\n]/.test(t))return;e.preventDefault();let n=e.currentTarget,a=n.selectionStart??i.value.length,o=n.selectionEnd??i.value.length;r(i.id,{value:i.value.slice(0,a)+t+i.value.slice(o),multiline:!0})}})}),!n&&H(`div`,{class:`custom-actions`,children:[H(`label`,{class:`check small`,children:[H(`input`,{type:`checkbox`,checked:i.hidden,"aria-label":`Hide ${i.label||`field`} value`,onChange:e=>r(i.id,{hidden:e.currentTarget.checked})}),` `,`Hidden`]}),H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Remove field`,title:`Remove`,onClick:()=>t({customFields:e.customFields.filter(e=>e.id!==i.id)}),children:H(U,{name:`x`})})]})]},i.id))]})},yr=({entry:e,update:t})=>{let{readOnly:n}=Z();return H(tr,{id:`${e.id}:notes`,title:`Notes`,summary:e.notes?er(e.notes.length,`character`):`empty`,defaultOpen:!!e.notes&&e.kind===`other`,children:[H(`textarea`,{class:`input`,rows:4,value:e.notes,placeholder:`Recovery instructions, inheritance notes, history…`,"aria-label":`Notes`,readOnly:n,onInput:e=>t({notes:e.currentTarget.value}),...Nt}),sr(e,e.notes)&&H(`p`,{class:`status status-error`,role:`status`,children:[H(U,{name:`alert`}),` This text repeats the entry's secret, and it is not hidden.`]})]})},br=e=>{let t=new Set;return e.split(`,`).map(e=>e.trim()).filter(e=>e&&!t.has(e.toLowerCase())&&t.add(e.toLowerCase()))},xr=({tags:e,onChange:t})=>{let{readOnly:n}=Z(),[r,i]=z(e.join(`, `));B(()=>{br(r).join(`,`)!==e.join(`,`)&&i(e.join(`, `))},[e.join(`,`)]);let a=n=>{i(n);let r=br(n);r.join(`,`)!==e.join(`,`)&&t(r)},o=()=>i(br(r).join(`, `));return H(`input`,{class:`input`,value:r,placeholder:`cold storage, inheritance`,readOnly:n,onInput:e=>a(e.currentTarget.value),onBlur:o,onKeyDown:e=>e.key===`Enter`&&o()})},Sr=({lock:e,onEditing:t,children:n})=>{let r=Z(),i=r.readOnly||e===`locked`,a=Ce(()=>i===r.readOnly?r:{...r,readOnly:i},[r,i]),o=e===`locked`;return H(Dt.Provider,{value:a,children:[e!==`off`&&!r.readOnly&&H(`div`,{class:`lock-bar ${e}`,children:[H(U,{name:o?`lock`:`edit`}),H(`span`,{children:o?`Locked against accidental changes.`:`Editing.`}),H(`button`,{type:`button`,class:`button small`,onClick:()=>t(o),children:[H(U,{name:o?`edit`:`check`}),` `,o?`Edit`:`Done`]})]}),n]})},Cr=({entry:e,onUpdate:t,onDelete:n,onDuplicate:r})=>{let{readOnly:i}=Z();return i?null:H(`div`,{class:`entry-actions`,children:[H(`button`,{type:`button`,class:`icon-button ${e.favorite?`active`:``}`,"aria-pressed":e.favorite,"aria-label":`Favorite`,title:`Favorite`,disabled:i,onClick:()=>t({favorite:!e.favorite}),children:H(U,{name:`star`,fill:e.favorite?`currentColor`:`none`})}),!i&&H(C,{children:[H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Duplicate`,title:`Duplicate`,onClick:r,children:H(U,{name:`duplicate`})}),H(`button`,{type:`button`,class:`icon-button ${e.archived?`active`:``}`,"aria-label":e.archived?`Unarchive`:`Archive`,title:e.archived?`Unarchive`:`Archive (e.g. an emptied or retired wallet)`,onClick:()=>t({archived:!e.archived}),children:H(U,{name:`archive`})}),H(`button`,{type:`button`,class:`icon-button danger`,"aria-label":`Delete`,title:`Delete`,onClick:n,children:H(U,{name:`trash`})})]})]})},wr=e=>{let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString()},Tr=({entry:e,reminderMonths:t,onUpdate:n,showLabel:r,focusLabel:i=!1})=>{let{readOnly:a}=Z(),o=e=>!a&&n(e),s=J[e.kind].secret;return H(`div`,{class:`entry-body`,children:[H(rr,{entry:e,update:o,showLabel:r,focusLabel:i}),s===`words`&&H(ir,{entry:e,update:o}),(s===`key`||s===`token`)&&H(ur,{entry:e,update:o}),s===`codes`&&H(dr,{entry:e,update:o}),s===`fields`&&H(vr,{entry:e,update:o}),Xe(e.kind)?H(gr,{entry:e,update:o}):H(hr,{entry:e,update:o}),s!==`fields`&&H(vr,{entry:e,update:o}),H(_r,{entry:e,update:o,reminderMonths:t}),H(yr,{entry:e,update:o}),H(`footer`,{class:`editor-footer muted small`,children:[`Added `,wr(e.addedAt),` · Updated `,wr(e.updatedAt)]})]})},Er=({entry:e,lock:t,reminderMonths:n,onUpdate:r,onDelete:i,onDuplicate:a,onEditing:o,onBack:s,focusLabel:c})=>{let l=Z().readOnly||t===`locked`,u=V(null);return B(()=>{c&&u.current?.focus()},[]),H(`article`,{class:`editor`,"aria-label":e.label||`Untitled entry`,children:[H(`header`,{class:`editor-header`,children:[H(`button`,{type:`button`,class:`icon-button back-button`,"aria-label":`Back to list`,title:`Back`,onClick:s,children:H(U,{name:`back`})}),H(`input`,{ref:u,class:`input title-input`,value:e.label,placeholder:yn(hn[e.kind]),"aria-label":`Label`,readOnly:l,onInput:e=>!l&&r({label:e.currentTarget.value})}),H(`span`,{class:`badge badge-${e.kind}`,children:hn[e.kind]}),H(Cr,{entry:e,onUpdate:r,onDelete:i,onDuplicate:a,onEditing:o})]}),H(`div`,{class:`editor-body`,children:H(Sr,{lock:t,onEditing:o,children:H(Tr,{entry:e,reminderMonths:n,onUpdate:r,showLabel:!1})})})]})},Dr=[[`all`,`All`],[`crypto`,`Crypto`],...Je.map(e=>[e,gn[e]]),[`favorites`,`Favorites`],[`attention`,`Backup check due`],[`expiring`,`Expiring or expired`],[`archived`,`Archived`]],Or=new Intl.Collator(void 0,{numeric:!0,sensitivity:`base`}),kr=(e,t)=>{if(!t)return!0;let n=[e.label,e.description,e.chain,e.wallet,e.service,e.account,e.notes,e.derivationPath,e.fingerprint,e.publicInfo,...e.tags,...e.customFields.flatMap(e=>e.hidden?[e.label]:[e.label,e.value]),...e.backups.map(e=>e.location)].join(` `).toLowerCase();return t.toLowerCase().split(/\s+/).every(e=>n.includes(e))},Ar=(e,t,n,r,i)=>e.filter(e=>t===`archived`?e.archived:!e.archived).filter(e=>{switch(t){case`all`:case`archived`:return!0;case`crypto`:return Xe(e.kind);case`favorites`:return e.favorite;case`attention`:return wt(e,i);case`expiring`:return Et(e);default:return e.kind===t}}).filter(e=>kr(e,r.trim())).sort((e,t)=>e.favorite===t.favorite?n===`label`?!e.label==!t.label?Or.compare(e.label,t.label):e.label?-1:1:n===`created`?(t.createdOn||``).localeCompare(e.createdOn||``):t.updatedAt.localeCompare(e.updatedAt):e.favorite?-1:1),jr=Je,Mr={none:``,kind:``,chain:`No chain or service`,wallet:`No wallet or account`,tag:`Untagged`},Nr=(e,t)=>{if(t===`none`)return[{key:`all`,label:``,entries:e}];let n=e=>t===`kind`?e.kind:t===`chain`?(e.chain||e.service).trim():t===`wallet`?(e.wallet||e.account).trim():(e.tags[0]??``).trim(),r=new Map;for(let i of e){let e=n(i),a=`${t}:${e.toLowerCase()}`,o=r.get(a);o||(o={key:a,label:t===`kind`?gn[e]:e||Mr[t],entries:[]},r.set(a,o)),o.entries.push(i)}let i=[...r.values()];if(t===`kind`)return i.sort((e,t)=>jr.indexOf(e.entries[0].kind)-jr.indexOf(t.entries[0].kind));let a=e=>e.key.endsWith(`:`);return i.sort((e,t)=>Number(a(e))-Number(a(t))||Or.compare(e.label,t.label))},Pr=e=>({order:e.flatMap(e=>e.entries.map(e=>e.id)),groupOf:new Map(e.flatMap(e=>e.entries.map(t=>[t.id,e.key]))),labelOf:new Map(e.map(e=>[e.key,e.label]))}),Fr=(e,t)=>{let n=new Map(t.order.map((e,t)=>[e,t])),r=new Map(e.flatMap(e=>e.entries.map(t=>[t.id,e.key]))),i=new Map(e.map(e=>[e.key,e.label])),a=e.flatMap(e=>e.entries).sort((e,t)=>(n.get(e.id)??-1)-(n.get(t.id)??-1)),o=new Map;for(let e of a){let n=t.groupOf.get(e.id)??r.get(e.id),a=o.get(n);a||(a={key:n,label:t.labelOf.get(n)??i.get(n)??``,entries:[]},o.set(n,a)),a.entries.push(e)}return[...new Set([...t.labelOf.keys(),...e.map(e=>e.key)])].flatMap(e=>o.get(e)??[])},Ir=({entry:e})=>{let t=At(()=>rn(e.scheme,e.words),[e.scheme,e.words.join(` `)]);return!t||t.status===`incomplete`||t.status===`unchecked`?null:t.status===`valid`?H(`span`,{class:`pill pill-ok`,title:t.message,children:[H(U,{name:`check`,size:12}),` checksum`]}):H(`span`,{class:`pill pill-error`,title:t.message,children:[H(U,{name:`alert`,size:12}),` check words`]})},Lr=({entry:e})=>{let t=Tt(e);return t===null||!Et(e)?null:t<0?H(`span`,{class:`pill pill-error`,title:`Expired ${e.expiresOn}`,children:`expired`}):H(`span`,{class:`pill pill-warn`,title:`Expires ${e.expiresOn}`,children:t===0?`expires today`:`expires in ${t} day${t===1?``:`s`}`})},Rr=({entry:e,reminderMonths:t,idPrefix:n})=>{let r=(Xe(e.kind)?[e.chain,e.wallet,e.kind===`mnemonic`?`${e.words.length} words`:``]:[hn[e.kind],e.service,e.account]).filter(Boolean).join(` · `);return H(C,{children:[H(`span`,{class:`entry-icon badge-${e.kind}`,title:hn[e.kind],children:H(U,{name:_n[e.kind]})}),H(`span`,{class:`entry-main`,children:[H(`span`,{class:`entry-title`,id:n&&`${n}-title`,children:[e.favorite&&H(U,{name:`star`,size:12,fill:`currentColor`,class:`star`}),e.label||H(`em`,{class:`muted`,children:yn(hn[e.kind])})]}),r&&H(`span`,{class:`entry-meta`,id:n&&`${n}-meta`,children:r}),H(`span`,{class:`entry-pills`,id:n&&`${n}-pills`,children:[e.kind===`mnemonic`&&H(Ir,{entry:e}),e.passphrase&&H(`span`,{class:`pill`,children:`+ passphrase`}),e.archived&&H(`span`,{class:`pill`,children:`archived`}),H(Lr,{entry:e}),wt(e,t)&&H(`span`,{class:`pill pill-warn`,children:e.backups.length?`backup check due`:`no backup recorded`}),e.tags.map(e=>H(`span`,{class:`pill`,children:e},e))]})]}),e.createdOn&&H(`span`,{class:`entry-date`,children:e.createdOn})]})},zr=({group:e,bare:t,collapsed:n,onToggle:r,children:i})=>{let a=`group-${e.key.replace(/[^a-z0-9]/gi,`-`)}`;return!e.label||t?H(`section`,{class:`group bare`,children:H(`div`,{id:a,children:i})}):H(`section`,{class:`group ${n?`collapsed`:``}`,children:[H(`h2`,{class:`group-heading`,children:H(`button`,{type:`button`,class:`group-toggle`,"aria-expanded":!n,"aria-controls":a,onClick:r,children:[H(U,{name:`chevron`,size:14,class:`chevron`}),H(`span`,{children:e.label}),H(`span`,{class:`count`,children:e.entries.length})]})}),!n&&H(`div`,{id:a,children:i})]})},Br=({groups:e,collapsedGroups:t,selectedId:n,reminderMonths:r,onSelect:i,onToggleGroup:a})=>H(`div`,{class:`entry-list`,children:e.map(o=>H(zr,{group:o,bare:e.length===1,collapsed:t.has(o.key)&&e.length>1,onToggle:()=>a(o.key),children:H(`ul`,{class:`entry-rows`,"aria-label":o.label||`Entries`,children:o.entries.map(e=>H(`li`,{children:H(`button`,{type:`button`,class:`entry-item ${e.id===n?`selected`:``}`,"aria-current":e.id===n,onClick:()=>i(e.id),children:H(Rr,{entry:e,reminderMonths:r})})},e.id))})},o.key))}),Vr=(e,t)=>{let n=Object.keys(e);return n.length===Object.keys(t).length&&n.every(n=>Object.is(e[n],t[n]))},Hr=(e=>class extends w{shouldComponentUpdate(e){return!Vr(this.props,e)}render(t){return x(e,t)}})(({entry:e,lock:t,open:n,reminderMonths:r,isNew:i,onToggle:a,...o})=>{let s=V(null);B(()=>{i&&s.current?.scrollIntoView({block:`nearest`})},[i]);let c=`entry-${e.id}`;return H(`li`,{ref:s,class:`card-entry ${n?`open`:``}`,children:[H(`div`,{class:`card-header`,children:[H(`button`,{type:`button`,class:`card-toggle`,"aria-expanded":n,"aria-controls":c,"aria-labelledby":`${c}-title`,"aria-describedby":`${c}-meta ${c}-pills`,onClick:()=>a(e.id),children:[H(U,{name:`chevron`,size:14,class:`chevron`}),H(Rr,{entry:e,reminderMonths:r,idPrefix:c})]}),n&&H(Cr,{entry:e,...o})]}),n&&H(`div`,{class:`card-body`,id:c,children:H(Sr,{lock:t,onEditing:o.onEditing,children:H(Tr,{entry:e,reminderMonths:r,onUpdate:o.onUpdate,showLabel:!0,focusLabel:i})})})]})}),Ur=({groups:e,expanded:t,collapsedGroups:n,reminderMonths:r,newId:i,lockFor:a,onToggle:o,onToggleGroup:s,handlersFor:c})=>H(`div`,{class:`stack`,children:e.map(l=>H(zr,{group:l,bare:e.length===1,collapsed:n.has(l.key)&&e.length>1,onToggle:()=>s(l.key),children:H(`ul`,{class:`cards`,"aria-label":l.label||`Entries`,children:l.entries.map(e=>H(Hr,{entry:e,lock:a(e.id),open:t.has(e.id),reminderMonths:r,isNew:e.id===i,onToggle:o,...c(e.id)},e.id))})},l.key))}),Wr=({label:e,icon:t,kind:n,buttonClass:r=`button small`,children:i})=>{let[a,o]=z(!1),s=V(null),c=V(null);return B(()=>{if(!a)return;let e=e=>{s.current?.contains(e.target)||o(!1)};return document.addEventListener(`pointerdown`,e),()=>document.removeEventListener(`pointerdown`,e)},[a]),H(`div`,{class:`popover-wrap`,ref:s,onKeyDown:e=>{e.key===`Escape`&&a&&(e.stopPropagation(),o(!1),c.current?.focus())},onFocusOut:e=>{let t=e.relatedTarget;t&&!s.current?.contains(t)&&o(!1)},children:[H(`button`,{type:`button`,ref:c,class:r,"aria-expanded":a,"aria-label":e,title:e,onClick:()=>o(!a),children:[H(U,{name:t}),` `,H(`span`,{class:`button-text`,children:e})]}),a&&H(`div`,{class:`popover popover-${n}`,children:i(()=>o(!1))})]})},Gr=[`crypto`,`keys`,`secrets`],Kr=({icon:e,label:t,onClick:n,disabled:r})=>H(`button`,{type:`button`,class:`button small`,"aria-label":t,title:t,onClick:n,disabled:r,children:[H(U,{name:e}),` `,H(`span`,{class:`button-text`,children:t})]}),qr=e=>{let t=e.view.layout===`stacked`;return H(`div`,{class:`toolbar`,children:[H(`div`,{class:`toolbar-row`,children:[H(`div`,{class:`search`,children:[H(U,{name:`search`}),H(`input`,{class:`input`,type:`search`,placeholder:`Search labels, tags, notes`,"aria-label":`Search`,value:e.query,onInput:t=>e.onQuery(t.currentTarget.value),spellcheck:!1})]}),H(`select`,{class:`input filter`,"aria-label":`Filter`,value:e.filter,onChange:t=>e.onFilter(t.currentTarget.value),children:Dr.map(([t,n])=>H(`option`,{value:t,children:[n,t===`attention`&&e.dueCount?` (${e.dueCount})`:``]}))}),!e.readOnly&&H(Wr,{label:`Add`,icon:`plus`,kind:`menu`,buttonClass:`button small primary add-button`,children:t=>Gr.map(n=>H(`div`,{role:`group`,"aria-label":Ye[n],class:`menu-group`,children:[H(`div`,{class:`menu-heading`,"aria-hidden":`true`,children:Ye[n]}),Je.filter(e=>J[e].group===n).map(n=>H(`button`,{type:`button`,class:`menu-item`,onClick:()=>{t(),e.onAdd(n)},children:[H(U,{name:_n[n]}),` `,hn[n]]}))]}))})]}),H(`div`,{class:`toolbar-row`,children:[H(`span`,{class:`muted small count`,role:`status`,children:e.shown===e.total?`${e.total} ${e.total===1?`entry`:`entries`}`:`${e.shown} of ${e.total} entries`}),H(`span`,{class:`spacer`}),t&&H(C,{children:[H(Kr,{icon:`expand`,label:`Expand all`,onClick:e.onExpandAll,disabled:e.view.singleExpand||e.shown===0}),H(Kr,{icon:`collapse`,label:`Collapse all`,onClick:e.onCollapseAll,disabled:e.shown===0})]}),H(Wr,{label:`View`,icon:`sliders`,kind:`dialog`,children:()=>H(`div`,{class:`view-options`,children:[H(`fieldset`,{children:[H(`legend`,{children:`Layout`}),H(`label`,{class:`check`,children:[H(`input`,{type:`radio`,name:`layout`,checked:t,onChange:()=>e.onView({layout:`stacked`})}),` Expandable cards`]}),H(`label`,{class:`check`,children:[H(`input`,{type:`radio`,name:`layout`,checked:!t,onChange:()=>e.onView({layout:`split`})}),` List + editor side by side`]})]}),H(`fieldset`,{children:[H(`legend`,{children:`Density`}),H(`label`,{class:`check`,children:[H(`input`,{type:`radio`,name:`density`,checked:e.view.density===`comfortable`,onChange:()=>e.onView({density:`comfortable`})}),` `,`Comfortable`]}),H(`label`,{class:`check`,children:[H(`input`,{type:`radio`,name:`density`,checked:e.view.density===`compact`,onChange:()=>e.onView({density:`compact`})}),` Compact`]})]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Group by`}),H(`select`,{class:`input`,value:e.view.groupBy,onChange:t=>e.onView({groupBy:t.currentTarget.value}),children:vn.map(([e,t])=>H(`option`,{value:e,children:t}))})]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Sort`}),H(`select`,{class:`input`,value:e.view.sort,onChange:t=>e.onView({sort:t.currentTarget.value}),children:[H(`option`,{value:`updated`,children:`Recently updated`}),H(`option`,{value:`label`,children:`Label`}),H(`option`,{value:`created`,children:`Date created`})]})]}),t&&H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:e.view.singleExpand,onChange:t=>e.onView({singleExpand:t.currentTarget.checked})}),` Open one entry at a time`]})]})}),H(Kr,{icon:`settings`,label:`Settings`,onClick:e.onSettings}),e.hasPassword&&H(Kr,{icon:`lock`,label:`Lock`,onClick:e.onLock}),H(Kr,{icon:`eyeOff`,label:`Hide all`,onClick:e.onHideAll})]})]})},Jr=6e5,Yr=16,Xr=12,Zr=Ue,Qr=1,$r=e=>G(`${Ze}|${Qr}|PBKDF2-SHA256|${e}|AES-256-GCM`),ei=async(e,t=q(Yr),n=Jr)=>{let r=await crypto.subtle.importKey(`raw`,K(G(e.normalize(`NFC`))),`PBKDF2`,!1,[`deriveKey`]);return{key:await crypto.subtle.deriveKey({name:`PBKDF2`,hash:`SHA-256`,salt:K(t),iterations:n},r,{name:`AES-GCM`,length:256},!1,[`encrypt`,`decrypt`]),salt:t,iterations:n}},ti=async(e,t)=>{let n=q(Xr),r=await crypto.subtle.encrypt({name:`AES-GCM`,iv:K(n),additionalData:K($r(t.iterations))},t.key,K(G(JSON.stringify(e))));return{kdf:`PBKDF2-SHA256`,iterations:t.iterations,salt:Ve(t.salt),cipher:`AES-256-GCM`,iv:Ve(n),ciphertext:Ve(new Uint8Array(r))}},ni=class extends Error{constructor(){super(`Wrong password, or the vault data is damaged.`)}},ri=class extends Error{constructor(){super(`The vault data in this note is damaged. Restore an earlier version from note history.`)}},ii=e=>{try{return He(e)}catch{throw new ri}},ai=class extends Error{constructor(){super(`This browser cannot decrypt vaults here: encryption needs a secure (https) page. Open the note in the Standard Notes app or at app.standardnotes.com.`)}},oi=async(e,t)=>{let n=ii(e.iv),r=ii(e.ciphertext),i;try{i=await crypto.subtle.decrypt({name:`AES-GCM`,iv:K(n),additionalData:K($r(e.iterations))},t.key,K(r))}catch{throw new ni}try{return _t(JSON.parse(Re(new Uint8Array(i))))}catch{throw new ri}},si=async(e,t)=>{if(!Zr())throw new ai;let n=await ei(t,ii(e.salt),e.iterations);return{vault:await oi(e,n),vaultKey:n}},ci=(e,t)=>e.salt===Ve(t.salt)&&e.iterations===t.iterations,li=`keyfold-viewer.html`,ui=`Encrypted backup of a Keyfold vault (https://github.com/nickstruglia/standard-notes-keyfold). To read it without Standard Notes, open ${li} (keep a copy next to this file; it is also at https://standardnotes.github.io/plugins/cdn/dist/static/io.github.nickstruglia.keyfold/dist/${li}) in a browser and choose this file; it works offline. To restore it, create a new Standard Notes note, change the note type to Keyfold, choose "Restore a backup file" and pick this file, then enter the backup password. `+et(`the password chosen when the backup was made`),di=(e=nt())=>`keyfold-backup-${e}.json`,fi=async(e,t,n=Jr)=>{let r=new Date().toISOString(),i=await ti({...e,settings:{...e.settings,lastExportedAt:r}},await ei(t,void 0,n));return{text:JSON.stringify({app:Ze,version:1,readme:ui,exportedAt:r,encryption:i},null,1)+` +`,fileName:di(),exportedAt:r,entries:e.entries.length}},pi=e=>{let t=e.settings.lastExportedAt;return t?e.entries.filter(e=>e.updatedAt>t||e.addedAt>t).length:e.entries.length},mi=e=>e===0?`Never`:e<60?`${e} seconds`:`${e/60} minute${e===60?``:`s`}`,hi=({value:e,options:t,format:n,onChange:r,disabled:i})=>H(`select`,{class:`input`,value:String(e),disabled:i,onChange:e=>r(Number(e.currentTarget.value)),children:[...new Set([...t,e])].sort((e,t)=>e-t).map(e=>H(`option`,{value:String(e),children:n(e)}))}),gi=new Set([`1234567890`,`12345678910`,`0123456789`,`1111111111`,`qwertyuiop`,`asdfghjkl;`,`password12`,`password123`,`password1!`,`password123!`,`iloveyou12`,`letmein123`,`welcome123`,`abcdefghij`,`qwerty1234`,`1q2w3e4r5t`,`q1w2e3r4t5`,`zaq12wsxcde`,`passw0rd123`,`administrator`,`trustno1234`,`football123`,`baseball12`]),_i=e=>{if(gi.has(e.toLowerCase()))return{bits:0,label:`Very common`,tone:`error`};let t=(/[a-z]/.test(e)?26:0)+(/[A-Z]/.test(e)?26:0)+(/[0-9]/.test(e)?10:0)+(/[^a-zA-Z0-9]/.test(e)?33:0),n=new Set(e).size,r=Math.round(Math.min(e.length,n*2)*Math.log2(Math.max(t,1)));return r<50?{bits:r,label:`Weak`,tone:`error`}:r<75?{bits:r,label:`Fair`,tone:`warn`}:{bits:r,label:`Strong`,tone:`ok`}},vi=10,yi={set:`Set password`,change:`Change password`,remove:`Remove password`,export:`Encrypt backup`},bi=({mode:e,onSubmit:t,onCancel:n})=>{let r=e===`change`||e===`remove`,i=e===`export`,a=kt(r),o=kt(!r),[s,c]=z(``),[l,u]=z(``),[d,f]=z(``),[p,m]=z(!1),[h,g]=z(!1),_={strength:Ee(),mismatch:Ee()},[v,y]=z(!1),[b,x]=z(``),S=_i(l),w=S.tone===`error`,T=e!==`remove`,E=d!==``&&d!==l,D=(!r||s.length>0)&&(!T||l.length>=vi&&l===d&&p&&(!w||h));return H(`form`,{class:`password-form`,onSubmit:async e=>{if(e.preventDefault(),D&&!v){y(!0),x(``);try{await t(s,l)}catch(e){x(e instanceof Error?e.message:String(e)),y(!1)}}},children:[r&&H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Current vault password`}),H(`input`,{class:`input`,type:`password`,autocomplete:`current-password`,value:s,onInput:e=>c(e.currentTarget.value),ref:a})]}),T&&H(C,{children:[H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:i?`Backup password`:`New vault password`}),H(`input`,{class:`input`,type:`password`,autocomplete:`new-password`,value:l,onInput:e=>u(e.currentTarget.value),ref:o,"aria-describedby":l?_.strength:void 0}),l&&H(`span`,{id:_.strength,class:`hint status-${S.tone}`,children:[S.label,` (~`,S.bits,` bits).`,` `,l.lengthf(e.currentTarget.value),"aria-invalid":E,"aria-describedby":E?_.mismatch:void 0}),E&&H(`span`,{id:_.mismatch,class:`hint status-error`,role:`alert`,children:`Passwords do not match.`})]}),w&&l.length>=vi&&H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:h,onChange:e=>g(e.currentTarget.checked)}),H(`span`,{children:i?`Use this weak password anyway. Anyone who finds the backup file could guess it quickly.`:`Use this weak password anyway. Someone with access to your Standard Notes account could guess it quickly.`})]}),e===`change`&&H(`p`,{class:`small status-warn`,children:[H(U,{name:`alert`}),` Older versions of this note in Standard Notes' note history still open with the old password. If it leaked, delete those revisions too.`]}),H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:p,onChange:e=>m(e.currentTarget.checked)}),H(`span`,{children:i?`I understand that if I forget this password, no one (not Standard Notes, not the developer) can open this backup.`:`I understand that if I forget this password, no one (not Standard Notes, not the developer) can recover the secrets in this note.`})]})]}),b&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` `,b]}),H(`div`,{class:`row`,children:[H(`button`,{type:`submit`,class:`button ${e===`remove`?`danger`:`primary`}`,disabled:!D||v,children:v?i?`Encrypting…`:`Working…`:yi[e]}),H(`button`,{type:`button`,class:`button`,onClick:n,disabled:v,children:`Cancel`})]})]})},xi=e=>`${(e/1024).toFixed(+(e<10240))} KB`,Si=({vault:e,mobileApp:t,onExport:n,onExported:r,onCopy:i})=>{let{toast:a}=Z(),[o,s]=z(!1),[c,l]=z(null),u=Ce(()=>{if(!c)return null;let e=new Blob([c.text],{type:`application/json`});return{url:URL.createObjectURL(e),size:e.size}},[c]);B(()=>{if(u)return()=>{setTimeout(()=>URL.revokeObjectURL(u.url),6e4)}},[u]);let d=V(null),f=V(null);B(()=>(t?f:d).current?.focus(),[u]);let p=e.settings.lastExportedAt,m=p?pi(e):0,h=Zr()?mt(e)?`This vault was saved by a newer version of Keyfold. Update Keyfold first, so the backup leaves nothing out.`:e.entries.length===0?`There is nothing to back up yet.`:``:`Your browser does not provide WebCrypto here, so a backup cannot be encrypted.`,g=async()=>{c&&(await i(c.text)?(r(c),a(`Backup copied. Paste it into a text file or another app; only its password opens it.`,`success`)):a(`Could not copy the backup: clipboard access was blocked.`,`error`))},_=c&&u&&H(`a`,{ref:d,class:`button ${t?``:`primary`}`,href:u.url,download:c.fileName,onClick:()=>r(c),children:[H(U,{name:`download`}),` Save file`]}),v=H(`button`,{ref:f,type:`button`,class:`button ${t?`primary`:``}`,onClick:g,children:[H(U,{name:`copy`}),` Copy as text`]});return H(`section`,{class:`section`,children:[H(`h3`,{children:[H(U,{name:`download`}),` Backup file`]}),H(`p`,{class:`small`,children:`Save an encrypted copy of this vault outside Standard Notes, for example on a flash drive, so you can still read it if Standard Notes is ever unavailable. The Keyfold offline viewer opens it in any browser, with no account and no internet connection.`}),H(`p`,{class:`muted small`,children:[p?`Last backup file: ${bn(p)}.`:`No backup file made yet.`,m>0&&` ${m} ${m===1?`entry was`:`entries were`} added or changed since.`]}),c&&u?H(`div`,{class:`backup-ready`,children:[H(`p`,{class:`status status-ok`,role:`status`,children:[H(U,{name:`check`}),` Encrypted `,c.entries,` `,c.entries===1?`entry`:`entries`,` into `,c.fileName,` (`,xi(u.size),`).`]}),H(`div`,{class:`row`,children:[t?v:_,t?_:v,H(`button`,{type:`button`,class:`button`,onClick:()=>l(null),children:`Done`})]}),(t||Mt())&&H(`p`,{class:`small`,children:[t?`The Standard Notes phone app may not save files from plugins. `:``,`If Save file does nothing, copy the text and paste it into a file or another app, or make the backup on a computer.`]}),H(`p`,{class:`muted small`,children:`Keep it somewhere other than Standard Notes, with the offline viewer next to it, and make a new one after adding or changing keys.`})]}):o?H(C,{children:[H(`p`,{class:`small`,children:`Choose a password for this backup. It can be your vault password or a different one, as long as you will still remember it in years.`}),H(bi,{mode:`export`,onSubmit:async(e,t)=>{l(await n(t)),s(!1)},onCancel:()=>s(!1)})]}):H(C,{children:[h&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` `,h]}),H(`div`,{class:`row`,children:[H(`button`,{type:`button`,class:`button primary`,disabled:!!h,onClick:()=>s(!0),children:[H(U,{name:`download`}),` Make a backup file`]}),H(`a`,{class:`button`,href:`https://standardnotes.github.io/plugins/cdn/dist/static/io.github.nickstruglia.keyfold/dist/${li}`,target:`_blank`,rel:`noopener noreferrer`,children:`Get the offline viewer`})]})]})]})},Ci=({vault:e,settings:t,hasPassword:n,onChange:r,onSetPassword:i,onChangePassword:a,onRemovePassword:o,onExport:s,onExported:c,onCopyBackup:l,mobileApp:u,onLock:d,onClose:f})=>{let{readOnly:p}=Z(),[m,h]=z(null);return H(`article`,{class:`editor settings`,children:[H(`header`,{class:`editor-header`,children:[H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Close settings`,title:`Back`,onClick:f,children:H(U,{name:`back`})}),H(`h2`,{children:`Vault settings`})]}),H(`div`,{class:`editor-body`,children:[H(`p`,{class:`muted small`,children:`Settings are saved in this note, so every device uses the same ones.`}),H(`section`,{class:`section`,children:[H(`h3`,{children:[H(U,{name:`eye`}),` Privacy`]}),H(`div`,{class:`row`,children:[H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Hide revealed secrets after`}),H(hi,{value:t.autoHideSeconds,options:[0,10,30,60,120,300],format:mi,disabled:p,onChange:e=>r({autoHideSeconds:e})})]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Clear clipboard after`}),H(hi,{value:t.clipboardClearSeconds,options:[0,10,20,30,60,120],format:mi,disabled:p,onChange:e=>r({clipboardClearSeconds:e})})]})]}),H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:t.hideOnBlur,disabled:p,onChange:e=>r({hideOnBlur:e.currentTarget.checked})}),H(`span`,{children:`Hide revealed secrets when the editor loses focus`})]}),H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:t.privacyScreen,disabled:p,onChange:e=>r({privacyScreen:e.currentTarget.checked})}),H(`span`,{children:`Privacy screen: blur the whole vault while the editor is not focused`})]}),H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:t.lockSavedEntries,disabled:p,onChange:e=>r({lockSavedEntries:e.currentTarget.checked})}),H(`span`,{children:`Open saved entries locked, so nothing changes by accident while scrolling. Use Edit on an entry to change it.`})]})]}),H(`section`,{class:`section`,children:[H(`h3`,{children:[H(U,{name:`shield`}),` Backup reminders`]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Flag entries whose backups were not checked within`}),H(hi,{value:t.backupReminderMonths,options:[0,3,6,12,24],format:e=>e===0?`Off`:`${e} months`,disabled:p,onChange:e=>r({backupReminderMonths:e})})]})]}),H(Si,{vault:e,mobileApp:u,onExport:s,onExported:c,onCopy:l}),H(`section`,{class:`section`,children:[H(`h3`,{children:[H(U,{name:`lock`}),` Vault password`]}),H(`p`,{class:`small`,children:`Standard Notes already end-to-end encrypts this note. A vault password adds a second layer: the note stays unreadable even to someone using your unlocked Standard Notes account, until the password is entered.`}),H(`p`,{class:`muted small`,children:[`AES-256-GCM, key derived with PBKDF2-SHA256 (`,Jr.toLocaleString(),` iterations). The key is kept only in memory while the vault is unlocked.`]}),!n&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` Older versions of this note in Standard Notes' note history are not re-encrypted. To keep no unprotected copy, set the password on a new, empty vault note before adding secrets, or delete the old revisions.`]}),Zr()?m?H(bi,{mode:m,onSubmit:async(e,t)=>{m===`set`&&await i(t),m===`change`&&await a(e,t),m===`remove`&&await o(e),h(null)},onCancel:()=>h(null)}):n?H(C,{children:[H(`p`,{class:`status status-ok`,children:[H(U,{name:`check`}),` This vault is password protected.`]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Lock automatically after inactivity`}),H(hi,{value:t.autoLockMinutes,options:[0,1,2,5,10,15,30,60],format:e=>e===0?`Never`:`${e} minute${e===1?``:`s`}`,disabled:p,onChange:e=>r({autoLockMinutes:e})})]}),H(`div`,{class:`row`,children:[H(`button`,{type:`button`,class:`button primary`,onClick:d,children:[H(U,{name:`lock`}),` Lock now`]}),H(`button`,{type:`button`,class:`button`,disabled:p,onClick:()=>h(`change`),children:`Change password`}),H(`button`,{type:`button`,class:`button danger`,disabled:p,onClick:()=>h(`remove`),children:`Remove password`})]})]}):H(`button`,{type:`button`,class:`button primary`,disabled:p,onClick:()=>h(`set`),children:[H(U,{name:`lock`}),` Set a vault password`]}):H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` Your browser does not provide WebCrypto here, so a vault password is not available.`]})]}),H(`section`,{class:`section`,children:[H(`h3`,{children:`About`}),H(`p`,{class:`small`,children:[`Keyfold `,`1.0.31 (77e7bd8)`,`, from `,`https://standardnotes.github.io/plugins/cdn/dist/static/io.github.nickstruglia.keyfold/dist/`,`. Open source (MIT):`,` `,H(`a`,{href:`https://github.com/nickstruglia/standard-notes-keyfold`,target:`_blank`,rel:`noopener noreferrer`,children:`github.com/nickstruglia/standard-notes-keyfold`}),`. Its Content Security Policy blocks all outgoing connections, images and fonts from other sites; only your Standard Notes theme's stylesheets load.`]}),H(`details`,{class:`notices`,children:[H(`summary`,{class:`small`,children:`Third-party notices`}),H(`p`,{class:`small`,children:`Monero seeds are checked against the Monero English wordlist, used under this licence:`}),H(`pre`,{class:`small`,children:Lt})]})]})]})]})},wi=e=>new Promise((t,n)=>{let r=new FileReader;r.onload=()=>t(String(r.result??``)),r.onerror=()=>n(r.error),r.readAsText(e)}),Ti=({offlineViewer:e,onOpen:t})=>{let[n,r]=z(``),[i,a]=z(``),[o,s]=z(!1),c=V(null),l=kt(),u=(e,n)=>{let r=yt(e).kind;if(r===`empty`)return a(n===`file`?`This file is empty.`:`Paste the text first.`);if(r===`foreign`)return a(n===`file`?`This file is not a Keyfold backup or note.`:`This is not the text of a Keyfold note. Copy all of it, from the first { to the last }, without editing.`);t(e)},d=async e=>{if(e){if(a(``),e.size>20971520)return a(`This file is too large to be a Keyfold backup.`);try{u(await wi(e),`file`)}catch{a(`Could not read this file.`)}}};return H(`div`,{class:`app`,children:H(`div`,{class:`screen ${o?`dragging`:``}`,onDragOver:e=>{e.preventDefault(),s(!0)},onDragLeave:e=>{e.currentTarget===e.target&&s(!1)},onDrop:e=>{e.preventDefault(),s(!1),d(e.dataTransfer?.files[0])},children:H(`form`,{class:`card open-note`,onSubmit:e=>{e.preventDefault(),a(``),u(n,`paste`)},children:[H(U,{name:`lock`,size:32}),H(`h2`,{children:e?`Keyfold offline viewer`:`Open a Keyfold backup or note`}),H(`p`,{class:`small`,children:[`Open a Keyfold backup file, or paste the text of a Keyfold note. It opens read-only. Nothing is saved, and this page cannot send anything anywhere`,e?`, so it works offline`:``,`.`]}),H(`input`,{ref:c,type:`file`,hidden:!0,"aria-label":`Backup file`,onChange:e=>{let t=e.currentTarget;d(t.files?.[0]).finally(()=>{t.value=``})}}),H(`button`,{ref:l,type:`button`,class:`button primary`,onClick:()=>c.current?.click(),children:[H(U,{name:`file`}),` Choose backup file`]}),!Mt()&&H(`p`,{class:`muted small`,children:`or drop it on this page`}),i&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` `,i]}),H(`details`,{class:`paste-note`,children:[H(`summary`,{children:`Paste a note's text instead`}),H(`p`,{class:`small`,children:`In Standard Notes, change the note type to Plain text, then select all and copy, without editing.`}),H(`textarea`,{class:`input mono`,rows:8,value:n,"aria-label":`Note text`,placeholder:`{ "app": "keyfold", ... }`,onInput:e=>r(e.currentTarget.value),autocomplete:`off`,spellcheck:!1}),H(`button`,{type:`submit`,class:`button`,disabled:!n.trim(),children:`Open read-only`})]}),location.protocol!==`file:`&&H(`a`,{class:`small`,href:`./keyfold-viewer.html`,download:`keyfold-viewer.html`,children:`Save this viewer as a single file, to keep next to your backups`}),!e&&H(`a`,{class:`small`,href:`./`,children:`Back to the demo`})]})})})},Ei=({mobileApp:e,vaultHasPassword:t,onRestore:n,onCancel:r})=>{let[i,a]=z(``),[o,s]=z(null),[c,l]=z(``),[u,d]=z(!1),[f,p]=z(``),[m,h]=z(!1),g=V(null),_=V(null),v=kt(!e);B(()=>{o&&_.current?.focus()},[o]);let y=async(e,t)=>{d(!0),p(``);try{await n(e,t)}catch(e){p(e instanceof Error?e.message:String(e)),d(!1)}},b=(e,t)=>{p(``);let n=yt(e);switch(n.kind){case`empty`:return p(t===`file`?`This file is empty.`:`Paste the text first.`);case`foreign`:return p(t===`file`?`This file is not a Keyfold backup.`:`This is not the text of a Keyfold backup or note. Copy all of it, from the first { to the last }, without editing.`);case`newer`:return p(`This was made by a newer version of Keyfold. Update the plugin in Standard Notes (Preferences → Plugins), then try again.`);case`unsupported`:return p(`Its encryption uses settings this copy of Keyfold cannot read, or the file is damaged.`);case`plain`:y(e,``);return;case`encrypted`:return s({text:e,exportedAt:n.exportedAt})}},x=async e=>{if(e){if(p(``),e.size>20971520)return p(`This file is too large to be a Keyfold backup.`);try{b(await wi(e),`file`)}catch{p(`Could not read this file.`)}}},S=f&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` `,f]});if(o){let e=o.exportedAt?`Backup password`:`Vault password`;return H(`div`,{class:`screen`,children:H(`form`,{class:`card restore-backup`,onSubmit:e=>{e.preventDefault(),c&&!u&&y(o.text,c)},children:[H(U,{name:`lock`,size:32}),H(`h2`,{children:o.exportedAt?`Encrypted backup`:`Encrypted vault`}),H(`p`,{class:`small`,children:[o.exportedAt?`Made ${bn(o.exportedAt)}. Enter the password chosen when the backup was made.`:`Enter the vault password of the note this text came from.`,` `,t?`This vault keeps its own password.`:`The restored vault keeps this password. You can change it in Settings.`]}),!Zr()&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` Encryption needs a secure (https) connection. Open the note in the Standard Notes app or at app.standardnotes.com.`]}),H(`input`,{ref:_,class:`input`,type:`password`,autocomplete:`current-password`,placeholder:e,"aria-label":e,value:c,onInput:e=>l(e.currentTarget.value)}),S,H(`div`,{class:`row`,children:[H(`button`,{type:`submit`,class:`button primary`,disabled:!c||u,children:u?`Restoring…`:`Restore`}),H(`button`,{type:`button`,class:`button`,disabled:u,onClick:()=>{s(null),l(``),p(``)},children:`Back`})]})]})})}return H(`div`,{class:`screen ${m?`dragging`:``}`,onDragOver:e=>{e.preventDefault(),h(!0)},onDragLeave:e=>{e.currentTarget===e.target&&h(!1)},onDrop:e=>{e.preventDefault(),h(!1),x(e.dataTransfer?.files[0])},children:H(`form`,{class:`card restore-backup`,onSubmit:e=>{e.preventDefault(),u||b(i,`paste`)},children:[H(U,{name:`file`,size:32}),H(`h2`,{children:`Restore a backup`}),H(`p`,{class:`small`,children:`Choose a Keyfold backup file, or paste its text. Its entries are restored into this note, which is empty.`}),H(`input`,{ref:g,type:`file`,hidden:!0,"aria-label":`Backup file`,onChange:e=>{let t=e.currentTarget;x(t.files?.[0]).finally(()=>{t.value=``})}}),H(`button`,{ref:v,type:`button`,class:`button primary`,disabled:u,onClick:()=>g.current?.click(),children:[H(U,{name:`file`}),` Choose backup file`]}),!Mt()&&H(`p`,{class:`muted small`,children:`or drop it here`}),e&&H(`p`,{class:`small`,children:`The Standard Notes phone app may not let plugins open files. If nothing happens, paste the text instead.`}),S,H(`details`,{class:`paste-note`,open:e,children:[H(`summary`,{children:`Paste the text instead`}),H(`textarea`,{class:`input mono`,rows:6,value:i,"aria-label":`Backup text`,placeholder:`{ "app": "keyfold", ... }`,onInput:e=>a(e.currentTarget.value),autocomplete:`off`,spellcheck:!1}),H(`button`,{type:`submit`,class:`button`,disabled:!i.trim()||u,children:`Continue`})]}),H(`button`,{type:`button`,class:`button`,disabled:u,onClick:r,children:`Cancel`})]})})},Di=({onUnlock:e,autoFocus:t,exportedAt:n})=>{let r=n?`Backup password`:`Vault password`,i=Zr(),a=kt(t&&i),[o,s]=z(``),[c,l]=z(!1),[u,d]=z(``);return H(`div`,{class:`screen`,children:H(`form`,{class:`card lock-card`,onSubmit:async t=>{if(t.preventDefault(),o&&!c){l(!0),d(``);try{await e(o)}catch(e){d(e instanceof Error?e.message:String(e)),l(!1)}}},children:[H(U,{name:`lock`,size:32}),H(`h2`,{children:n?`Encrypted backup`:`Vault locked`}),H(`p`,{class:`muted small`,children:n?`Made ${bn(n)}. Enter the password chosen when the backup was made.`:`This note has an extra vault password. Standard Notes cannot recover it for you.`}),!i&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` This page cannot decrypt vaults: encryption needs a secure (https) connection. Open the note in the Standard Notes app or at app.standardnotes.com.`]}),H(`input`,{class:`input`,type:`password`,autocomplete:`current-password`,placeholder:r,"aria-label":r,value:o,disabled:!i,onInput:e=>s(e.currentTarget.value),ref:a}),u&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` `,u]}),H(`button`,{type:`submit`,class:`button primary`,disabled:!o||c,children:c?`Unlocking…`:`Unlock`})]})})},Oi=({length:e,readOnly:t,onConvert:n})=>H(`div`,{class:`screen`,children:H(`div`,{class:`card`,children:[H(U,{name:`alert`,size:32}),H(`h2`,{children:`This note already has other content`}),H(`p`,{class:`small`,children:[`It holds `,e.toLocaleString(),` characters that are not a Keyfold vault. Nothing has been changed.`]}),H(`p`,{class:`small`,children:`To keep the note as it is, switch it back to another editor in Standard Notes. Or convert it: the existing text is kept, line breaks included, in a hidden field of a new "Imported note" entry.`}),H(`button`,{type:`button`,class:`button primary`,disabled:t,onClick:n,children:`Convert to a vault`})]})}),ki=({version:e})=>H(`div`,{class:`screen`,children:H(`div`,{class:`card`,children:[H(U,{name:`alert`,size:32}),H(`h2`,{children:`Saved by a newer version`}),H(`p`,{class:`small`,children:[`This vault uses format version `,e,`, which this copy of Keyfold does not understand yet. Nothing has been changed. Update the plugin in Standard Notes (Preferences → Plugins) to open it.`]})]})}),Ai=()=>H(`div`,{class:`screen`,children:H(`div`,{class:`card`,children:[H(U,{name:`alert`,size:32}),H(`h2`,{children:`Vault encryption not recognized`}),H(`p`,{class:`small`,children:`This is a Keyfold vault, but its password protection uses settings this copy of Keyfold cannot read, or the data is damaged. Nothing has been changed. Update the plugin in Standard Notes (Preferences → Plugins), or restore an earlier version from note history.`})]})}),ji=({slow:e})=>H(`div`,{class:`screen`,children:H(`div`,{class:`card`,children:[H(`p`,{class:`muted`,children:`Connecting to Standard Notes…`}),e&&H(`p`,{class:`small muted`,children:`Still waiting. If Standard Notes asks to activate Keyfold, choose Continue; otherwise, close and reopen the note.`})]})}),Mi=({dialog:e,onClose:t})=>{let[n]=z(()=>document.activeElement),r=kt();return B(()=>()=>{n?.isConnected&&n.focus()},[]),B(()=>{let e=e=>e.key===`Escape`&&t(!1);return document.addEventListener(`keydown`,e),()=>document.removeEventListener(`keydown`,e)},[t]),H(`div`,{class:`overlay`,role:`presentation`,onClick:e=>e.target===e.currentTarget&&t(!1),onKeyDown:e=>{if(e.key!==`Tab`)return;let t=Array.from(e.currentTarget.querySelectorAll(`button`)),n=t[0],r=t[t.length-1];e.shiftKey&&document.activeElement===n?(e.preventDefault(),r.focus()):!e.shiftKey&&document.activeElement===r&&(e.preventDefault(),n.focus())},children:H(`div`,{class:`card dialog`,role:`alertdialog`,"aria-modal":`true`,"aria-labelledby":`dialog-title`,"aria-describedby":`dialog-message`,children:[H(`h2`,{id:`dialog-title`,children:e.title}),H(`p`,{id:`dialog-message`,class:`small`,children:e.message}),H(`div`,{class:`row end`,children:[H(`button`,{type:`button`,class:`button`,onClick:()=>t(!1),ref:r,children:`Cancel`}),H(`button`,{type:`button`,class:`button ${e.danger?`danger`:`primary`}`,onClick:()=>t(!0),children:e.confirmLabel??`OK`})]})]})})},Ni=({toasts:e,onDismiss:t})=>H(`div`,{class:`toasts`,role:`status`,"aria-live":`polite`,children:e.map(e=>H(`div`,{class:`toast toast-${e.tone}`,children:[H(`span`,{children:e.message}),e.action&&H(`button`,{type:`button`,class:`button small`,onClick:()=>{e.action.run(),t(e.id)},children:e.action.label}),H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Dismiss`,onClick:()=>t(e.id),children:H(U,{name:`x`,size:14})})]},e.id))}),Pi=e=>{let t=document.activeElement,n=t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement?t:null,r=n?[n.selectionStart,n.selectionEnd]:null,i=document.createElement(`textarea`);i.value=e,i.setAttribute(`readonly`,``),i.style.position=`fixed`,i.style.opacity=`0`,document.body.appendChild(i),i.select(),i.setSelectionRange(0,e.length);let a=!1;try{a=document.execCommand(`copy`)}catch{a=!1}if(i.remove(),t?.focus?.({preventScroll:!0}),n&&r&&r[0]!==null&&r[1]!==null)try{n.setSelectionRange(r[0],r[1])}catch{}return a},Fi=async e=>{if(Pi(e))return!0;try{if(navigator.clipboard?.writeText)return await navigator.clipboard.writeText(e),!0}catch{}return!1},Ii=()=>Pi(` `),Li=async()=>{if(Ii())return!0;try{if(navigator.clipboard?.writeText)return await navigator.clipboard.writeText(``),!0}catch{}return!1},Ri=2e3,zi=class{host;onError;delayMs;maxWaitMs;version=0;ready=null;timer;inflight=Promise.resolve();unsentSince=null;readyVersion=0;pending=[];lastText=``;constructor(e,t,n=300,r=1e3){this.host=e,this.onError=t,this.delayMs=n,this.maxWaitMs=r}schedule(e){let t=++this.version;this.unsentSince??=Date.now();let n=async()=>{if(t===this.version)try{let n=await e();if(t!==this.version)return;this.ready=n,this.readyVersion=t,clearTimeout(this.timer);let r=this.unsentSince??Date.now(),i=Math.max(0,Math.min(this.delayMs,r+this.maxWaitMs-Date.now()));this.timer=setTimeout(()=>this.flush(),i)}catch(e){t===this.version&&this.onError(e)}};this.inflight=this.inflight.then(n)}flush(){clearTimeout(this.timer),this.timer=void 0;let e=this.ready;e&&(this.ready=null,this.readyVersion===this.version&&(this.unsentSince=null),this.remember(e.text),this.host.save(e.text,e.preview))}hasUnsent(){return this.unsentSince!==null}async settle(){await this.inflight,this.flush()}cancel(){this.version++,clearTimeout(this.timer),this.timer=void 0,this.ready=null,this.unsentSince=null}isEcho(e){let t=Date.now();this.pending=this.pending.filter(e=>t-e.att.text===e);return n===-1?e!==``&&e===this.lastText:(this.pending.splice(0,n),!0)}forget(){this.cancel(),this.pending=[]}noteSeen(e){this.lastText=e}remember(e){this.lastText=e,this.pending.push({text:e,at:Date.now()}),this.pending.length>20&&this.pending.shift()}},Bi=e=>e instanceof Error?e.message:String(e),Vi=H(`datalist`,{id:`bip39-words`,children:It.map(e=>H(`option`,{value:e}))}),Hi=H($n,{}),Ui=`The note changed while this was running. Please try again.`,Wi=({host:e})=>{let[t,n]=z({name:`connecting`}),[r,i]=z(rt),[a,o]=z(!1),[s,c]=z(!1),[l,u]=z(0),[d,f]=z(()=>document.hasFocus()),[p,m]=z(!1),[h,g]=z({type:`list`}),[_,v]=z(``),[y,b]=z(`all`),[x,S]=z(()=>new Set),[w,T]=z(()=>new Set),[E,D]=z({}),[O,ee]=z({}),[te,k]=z(null),[ne,re]=z([]),[ie,ae]=z(null),[oe,se]=z(!1),[ce,le]=z(()=>new Set),A=V(r),j=V(null),ue=V(!1),M=V(0),de=V(0),fe=V(0),N=V(null),pe=we(e=>re(t=>t.filter(t=>t.id!==e)),[]),P=we((e,t=`info`,n,r=4e3)=>{let i=++fe.current;return re(r=>{let a=[...r,{id:i,message:e,tone:t,action:n}];for(;a.length>4;){let e=a.findIndex(e=>!e.action&&e.id!==i);a.splice(e===-1?0:e,1)}return a}),setTimeout(()=>pe(i),r),i},[]),F=Ce(()=>new zi(e,e=>P(`Could not save: ${Bi(e)}`,`error`,void 0,8e3)),[e]),I=async e=>{let t=j.current;return t?{text:xt(await ti(e,t)),preview:St(null)}:{text:bt(e),preview:St(e)}},me=e=>{A.current=e,i(e)},he=mt(r),L=a||he||t.name!==`ready`,ge=V(L);ge.current=L;let _e=V(a);_e.current=a;let ve=()=>{let e=M.current;return()=>{if(e!==M.current)throw Error(Ui);if(ge.current)throw Error(`This note is read-only right now.`)}},ye=()=>{j.current=null,F.cancel(),me(rt()),u(e=>e+1),g({type:`list`}),S(new Set),le(new Set),D({}),k(null),re([]),ae(e=>(e?.resolve(!1),null))},be=we(e=>{if(ge.current)return!1;let t=e(A.current);return me(t),F.schedule(()=>I(t)),!0},[F]);B(()=>{e.subscribe(async e=>{if(o(e.locked),e.metadataOnly||F.isEcho(e.text))return;let t=F.hasUnsent();F.cancel(),F.noteSeen(e.text);let r=++M.current,i=r===1,a=yt(e.text),s=()=>t&&P(`A newer version arrived from another device or note history and replaced your last few keystrokes.`,`error`,void 0,8e3);switch(a.kind){case`empty`:case`plain`:{let e=ue.current;j.current&&ye(),ue.current=!1,c(!1),me(a.kind===`plain`?a.vault:rt()),n({name:`ready`}),e&&!i?P(`This vault is no longer password protected: the note was changed on another device or restored from history. Set a password again in Settings if this was not you.`,`error`,void 0,6e4):s();return}case`encrypted`:{c(!0),ue.current=!0;let e=j.current;if(e&&ci(a.blob,e))try{let t=await oi(a.blob,e);if(r!==M.current)return;F.cancel(),me(t),n({name:`ready`}),s();return}catch{}if(r!==M.current)return;j.current&&ye(),me(rt()),n({name:`locked`,blob:a.blob,autoFocus:i||document.hasFocus(),exportedAt:a.exportedAt});return}case`foreign`:case`newer`:case`unsupported`:j.current&&ye(),ue.current=!1,c(!1),n(a.kind===`foreign`?{name:`foreign`,text:a.text}:a.kind===`newer`?{name:`newer`,version:a.version}:{name:`unsupported`});return}})},[e,F]),B(()=>{let e=setTimeout(()=>m(!0),5e3);return()=>clearTimeout(e)},[]);let R=r.settings,xe=V(R);xe.current=R,B(()=>{let e=()=>F.flush(),t=()=>{F.flush(),f(!1),xe.current.hideOnBlur&&u(e=>e+1)},n=()=>f(!0),r=()=>document.visibilityState===`hidden`&&F.flush();return window.addEventListener(`blur`,t),window.addEventListener(`focus`,n),window.addEventListener(`pagehide`,e),window.addEventListener(`beforeunload`,e),document.addEventListener(`visibilitychange`,r),()=>{window.removeEventListener(`blur`,t),window.removeEventListener(`focus`,n),window.removeEventListener(`pagehide`,e),window.removeEventListener(`beforeunload`,e),document.removeEventListener(`visibilitychange`,r)}},[F]);let Se=we(async(e=!1)=>{e&&N.current&&Ii()&&(N.current.blockedToast&&pe(N.current.blockedToast),N.current=null,de.current++),document.activeElement instanceof HTMLElement&&document.activeElement.blur(),await F.settle();let t=yt(F.lastText);t.kind===`encrypted`?(ye(),n({name:`locked`,blob:t.blob,autoFocus:e||document.hasFocus(),exportedAt:t.exportedAt})):(c(!1),e&&P(`This note is not password protected, so it cannot be locked.`,`error`))},[F]);B(()=>{if(!s||t.name!==`ready`||!R.autoLockMinutes)return;let e=Date.now(),n=()=>e=Date.now(),r=[`pointerdown`,`keydown`,`input`,`wheel`,`touchstart`];r.forEach(e=>window.addEventListener(e,n,{passive:!0}));let i=()=>{Date.now()-e>=R.autoLockMinutes*6e4&&Se()},a=setInterval(i,5e3);return document.addEventListener(`visibilitychange`,i),window.addEventListener(`pageshow`,i),window.addEventListener(`focus`,i),()=>{r.forEach(e=>window.removeEventListener(e,n)),clearInterval(a),document.removeEventListener(`visibilitychange`,i),window.removeEventListener(`pageshow`,i),window.removeEventListener(`focus`,i)}},[s,t.name,R.autoLockMinutes,Se]);let Te=async e=>{if(t.name!==`locked`)return;let r=M.current,{vault:i,vaultKey:a}=await si(t.blob,e);if(r!==M.current){let e=yt(F.lastText);if(e.kind!==`encrypted`||!ci(e.blob,a))throw Error(Ui);let t=M.current;if(i=await oi(e.blob,a),t!==M.current)throw Error(Ui)}if(j.current=a,me(i),n({name:`ready`}),a.iterations<6e5){let t=ve(),n=await ei(e);try{t()}catch{return}j.current=n,F.schedule(()=>I(A.current))}},Ee=async e=>{await F.settle();let t=yt(F.lastText);if(t.kind!==`encrypted`)throw Error(`The vault is not password protected.`);await si(t.blob,e)},De=async e=>{let t=ve(),n=await ei(e);t(),j.current=n,ue.current=!0,c(!0),F.schedule(()=>I(A.current)),P(`Vault password set. The note is now encrypted with it.`,`success`)},Oe=async(e,t)=>{let n=ve();await Ee(e);let r=await ei(t);n(),j.current=r,F.schedule(()=>I(A.current)),P(`Vault password changed.`,`success`)},ke=async e=>{let t=ve();await Ee(e),t(),j.current=null,ue.current=!1,c(!1),F.schedule(()=>I(A.current)),P(`Vault password removed. Standard Notes encryption still protects the note.`,`success`)};B(()=>{r.entries.length>0&&se(!1)},[r.entries.length]);let Ae=async(e,t)=>{let n=ve(),r=yt(e),i=j.current,a,o=i;if(r.kind===`plain`)a=r.vault;else if(r.kind===`encrypted`){let e=await si(r.blob,t);a=e.vault,o??=e.vaultKey.iterations<6e5?await ei(t):e.vaultKey}else throw Error(`This is not a Keyfold backup.`);if(mt(a))throw Error(`This was made by a newer version of Keyfold. Update the plugin in Standard Notes (Preferences → Plugins), then try again.`);if(n(),A.current.entries.length>0)throw Error(`Entries were added to this note meanwhile. Restore into a new, empty note.`);j.current=o,ue.current=o!==null,c(o!==null),me(a),se(!1),F.schedule(()=>I(a));let s=`${a.entries.length} ${a.entries.length===1?`entry`:`entries`}`;P(i?`Restored ${s}. The vault keeps its own password.`:o?`Restored ${s}. The vault keeps the password you entered; you can change it in Settings.`:`Restored ${s}. This vault has no password of its own; you can set one in Settings.`,`success`,void 0,8e3)},je=e=>{if(mt(A.current))throw Error(`Update Keyfold before making a backup of this vault.`);return fi(A.current,e)},Me=async e=>await Fi(e)?(de.current++,N.current?.blockedToast&&pe(N.current.blockedToast),N.current=null,!0):!1,Ne=we(e=>{let t=xe.current.clipboardClearSeconds,n=++de.current;N.current?.blockedToast&&pe(N.current.blockedToast),N.current=t?{id:n}:null;let r=Mt(),i=t?`${e} copied. The clipboard is cleared after ${t}s, on your next click or tap here if the browser requires one. It stays copied if you leave this note first.`:`${e} copied.`;if(P(r?`${i} Your keyboard's clipboard history may keep its own copy.`:i,`success`,void 0,r?8e3:6e3),!t)return;let a=()=>{N.current?.blockedToast&&pe(N.current.blockedToast),N.current?.id===n&&(N.current=null),r?P(`Clipboard cleared. Delete it from your keyboard's clipboard history too.`,`info`,void 0,6e3):P(`Clipboard cleared.`,`info`,void 0,3e3)};setTimeout(async()=>{if(n!==de.current)return;if(await Li()){a();return}let e=[`click`,`touchend`,`pointerup`],t=!1,r=()=>e.forEach(e=>window.removeEventListener(e,i,!0)),i=()=>{if(!t){if(n!==de.current)return r();Ii()&&(t=!0,r(),a())}};e.forEach(e=>window.addEventListener(e,i,!0));let o=P(`Waiting for a click or tap to clear the clipboard.`,`info`,{label:`Clear now`,run:i},2e4);N.current?.id===n&&(N.current.blockedToast=o)},t*1e3)},[P]),Pe=we(async(e,t)=>{e&&(await Fi(e)?Ne(t):P(`Could not copy ${t.toLowerCase()}: clipboard access was blocked.`,`error`))},[Ne]);B(()=>{let e=e=>{e.target?.closest?.(`[data-secret]`)&&Ne(`Selection`)};return document.addEventListener(`copy`,e,!0),document.addEventListener(`cut`,e,!0),()=>{document.removeEventListener(`copy`,e,!0),document.removeEventListener(`cut`,e,!0)}},[Ne]);let Fe=we(e=>new Promise(t=>ae({...e,resolve:t})),[]),Ie=Ce(()=>({settings:R,readOnly:L,hideEpoch:l,copy:Pe,toast:P,confirm:Fe,sectionOpen:(e,t)=>E[e]??t,setSectionOpen:(e,t)=>D(n=>({...n,[e]:t}))}),[R,L,l,Pe,P,Fe,E]),W={layout:R.layout,density:R.density,singleExpand:R.singleExpand,groupBy:R.groupBy,sort:R.sort,...O},Le=e=>{ee(t=>({...t,...e})),be(t=>({...t,settings:{...t.settings,...e}}))},G=W.singleExpand,Re=we(e=>{k(null),S(t=>{if(t.has(e)){let n=new Set(t);return n.delete(e),n}return G?new Set([e]):new Set(t).add(e)})},[G]),ze=we(e=>T(t=>{let n=new Set(t);return n.delete(e)||n.add(e),n}),[]),Be=e=>{b(`all`),v(``),T(new Set),k(e),S(t=>W.singleExpand?new Set([e]):new Set(t).add(e)),g({type:`entry`,id:e}),le(t=>new Set(t).add(e))},Ve=(e,t)=>le(n=>{let r=new Set(n);return t?r.add(e):r.delete(e),r}),He=e=>{let t=it(e);be(e=>({...e,entries:[t,...e.entries]})),Be(t.id)},Ue=(e,t)=>{be(n=>({...n,entries:n.entries.map(n=>n.id===e?{...n,...t,updatedAt:new Date().toISOString()}:n)}))&&t.archived===!0&&P(`Archived. It is under the "Archived" filter.`,`info`,{label:`Undo`,run:()=>Ue(e,{archived:!1})},6e3)},K=e=>{let t=A.current.entries.find(t=>t.id===e);if(!t)return;let n=new Date().toISOString(),r={...JSON.parse(JSON.stringify(t)),id:qe(),label:t.label?`${t.label} (copy)`:``,archived:!1,addedAt:n,updatedAt:n};be(e=>({...e,entries:[r,...e.entries]})),Be(r.id)},We=async e=>{let t=A.current.entries.findIndex(t=>t.id===e),n=A.current.entries[t];n&&await Fe({title:`Delete this entry?`,message:`"${n.label||`Untitled`}" will be removed from this note. You can undo right after, and Standard Notes keeps note history.`,confirmLabel:`Delete`,danger:!0})&&A.current.entries.some(t=>t.id===e)&&(be(t=>({...t,entries:t.entries.filter(t=>t.id!==e)}))?(g({type:`list`}),S(t=>{let n=new Set(t);return n.delete(e),n}),P(`Deleted "${n.label||`Untitled`}".`,`info`,{label:`Undo`,run:()=>{A.current.entries.some(e=>e.id===n.id)||be(e=>{let r=[...e.entries];return r.splice(Math.min(t,r.length),0,n),{...e,entries:r}})}},1e4)):P(`Nothing was deleted: the note is read-only right now.`,`error`))},Ge=e=>be(t=>({...t,settings:{...t.settings,...e}})),Ke=async e=>{let t=M.current;if(!await Fe({title:`Convert this note?`,message:`The existing text is moved into a hidden field of a new "Imported note" entry, and the note becomes a vault.`,confirmLabel:`Convert`})||t!==M.current||_e.current)return;let r=rt();r.entries.push(it(`other`,{label:`Imported note`,customFields:[{id:qe(),label:`Imported text`,value:e,hidden:!0,multiline:!0}]})),me(r),n({name:`ready`}),c(j.current!==null),F.schedule(()=>I(r))},q=h.type===`entry`?r.entries.find(e=>e.id===h.id)??null:null,J=r.entries.filter(e=>wt(e,R.backupReminderMonths)).length,Ye=W.layout===`stacked`?x.size>0:q!==null,Xe=[W.layout,W.sort,W.groupBy,y,_,W.layout===`stacked`?``:q?.id].join(`|`),Ze=V(null),Qe=Ye&&Ze.current?.key===Xe?Ze.current.snapshot:null,$e=Ar(r.entries,y,W.sort,_,R.backupReminderMonths);if(Qe){let e=new Set($e.map(e=>e.id));$e=[...$e,...r.entries.filter(t=>!e.has(t.id)&&Qe.groupOf.has(t.id))]}let et=Nr($e,W.groupBy);Qe&&(et=Fr(et,Qe)),Ze.current={key:Xe,snapshot:Pr(et)};let tt=V({updateEntry:Ue,deleteEntry:We,duplicateEntry:K,setEntryEditing:Ve});tt.current={updateEntry:Ue,deleteEntry:We,duplicateEntry:K,setEntryEditing:Ve};let Y=V(new Map),nt=e=>{let t=Y.current.get(e);return t||(t={onUpdate:t=>tt.current.updateEntry(e,t),onDelete:()=>tt.current.deleteEntry(e),onDuplicate:()=>tt.current.duplicateEntry(e),onEditing:t=>tt.current.setEntryEditing(e,t)},Y.current.set(e,t)),t},X=e=>R.lockSavedEntries?ce.has(e)?`editing`:`locked`:`off`,at=W.layout===`stacked`;B(()=>{le(e=>{let t=e=>at?x.has(e):h.type===`entry`&&h.id===e,n=new Set([...e].filter(t));return n.size===e.size?e:n})},[x,h,at]);let ot=H(`div`,{class:`empty`,children:[H(U,{name:`shield`,size:28}),H(`p`,{children:H(`strong`,{children:`No keys yet.`})}),H(`p`,{class:`small muted`,children:`Keep crypto seed phrases and wallet keys here, and also SSH, PGP and API keys, recovery codes and any other secret. Each one folds into a single line until you open it, and secrets stay hidden until you reveal them.`}),!L&&H(C,{children:[H(`p`,{class:`small`,children:`What do you want to add first?`}),H(`div`,{class:`kind-choices`,role:`group`,"aria-label":`Add your first entry`,children:Je.map(e=>H(`button`,{type:`button`,class:`button small`,onClick:()=>He(e),children:[H(U,{name:_n[e]}),` `,hn[e]]}))}),H(`p`,{class:`small muted`,children:`Add more of any type later with the Add (+) button.`}),H(`p`,{class:`small`,children:H(`button`,{type:`button`,class:`link-button`,onClick:()=>se(!0),children:`Restore a backup file`})})]})]}),st=r.entries.length>0&&r.entries.every(e=>e.archived)&&y!==`archived`?H(`p`,{class:`empty small muted`,children:[`Every entry is archived.`,` `,H(`button`,{type:`button`,class:`link-button`,onClick:()=>b(`archived`),children:`Show archived entries`})]}):H(`p`,{class:`empty small muted`,children:`No entries match.`}),ct;switch(t.name){case`connecting`:ct=H(ji,{slow:p});break;case`locked`:ct=H(Di,{onUnlock:Te,autoFocus:t.autoFocus,exportedAt:t.exportedAt});break;case`foreign`:ct=H(Oi,{length:t.text.length,readOnly:a,onConvert:()=>Ke(t.text)});break;case`newer`:ct=H(ki,{version:t.version});break;case`unsupported`:ct=H(Ai,{});break;case`ready`:{let t=H(qr,{query:_,onQuery:v,filter:y,onFilter:b,dueCount:J,shown:$e.length,total:r.entries.filter(e=>y===`archived`?e.archived:!e.archived).length,readOnly:L,onAdd:He,view:W,onView:Le,onExpandAll:()=>{T(new Set),S(new Set($e.map(e=>e.id)))},onCollapseAll:()=>{k(null),S(new Set)},onSettings:()=>g({type:`settings`}),hasPassword:s,onLock:()=>Se(!0),onHideAll:()=>{u(e=>e+1),le(new Set)}});ct=h.type===`settings`?H(`main`,{class:`detail full`,children:H(Ci,{vault:r,settings:R,hasPassword:s,onChange:Ge,onSetPassword:De,onChangePassword:Oe,onRemovePassword:ke,onExport:je,onExported:e=>Ge({lastExportedAt:e.exportedAt}),onCopyBackup:Me,mobileApp:e.inMobileApp(),onLock:()=>Se(!0),onClose:()=>g({type:`list`})})}):W.layout===`stacked`?H(C,{children:[t,H(`main`,{class:`detail full`,children:r.entries.length===0?ot:$e.length===0?st:H(Ur,{groups:et,expanded:x,collapsedGroups:w,reminderMonths:R.backupReminderMonths,newId:te,lockFor:X,onToggle:Re,onToggleGroup:ze,handlersFor:nt})})]}):H(C,{children:[t,H(`div`,{class:`layout ${q?`has-detail`:``}`,children:[H(`aside`,{class:`sidebar`,children:r.entries.length===0?ot:$e.length===0?st:H(Br,{groups:et,collapsedGroups:w,selectedId:q?.id??null,reminderMonths:R.backupReminderMonths,onSelect:e=>{k(null),g({type:`entry`,id:e})},onToggleGroup:ze})}),H(`main`,{class:`detail`,children:q?H(Er,{entry:q,lock:X(q.id),reminderMonths:R.backupReminderMonths,focusLabel:q.id===te,onBack:()=>{k(null),g({type:`list`})},...nt(q.id)},q.id):H(`div`,{class:`placeholder muted`,children:[H(U,{name:`shield`,size:36}),H(`p`,{children:`Select an entry, or add a new one.`})]})})]})]}),oe&&r.entries.length===0&&!L&&(ct=H(Ei,{mobileApp:e.inMobileApp(),vaultHasPassword:s,onRestore:Ae,onCancel:()=>se(!1)}))}}return H(Dt.Provider,{value:Ie,children:[H(`div`,{class:`app ${W.density} ${R.privacyScreen&&!d&&t.name===`ready`?`privacy`:``}`,children:[e.mode===`demo`&&H(`div`,{class:`banner banner-warn`,role:`note`,children:[H(U,{name:`alert`}),` Demo mode: not connected to Standard Notes, nothing is saved. Do not type real secrets here. To install, add `,H(`code`,{children:new URL(`ext.json`,location.href).href}),` in Standard Notes → Preferences → Plugins.`,` `,`Lost access to Keyfold? `,H(`a`,{href:`#open`,onClick:()=>setTimeout(()=>location.reload()),children:`Open a backup or note read-only`}),`.`]}),e.mode===`viewer`&&H(`div`,{class:`banner`,role:`note`,children:[H(U,{name:`lock`}),` Read-only viewer: nothing you open here is saved or sent anywhere.`,H(`button`,{type:`button`,class:`link-button`,onClick:()=>location.reload(),children:`Close`})]}),he&&t.name===`ready`&&H(`div`,{class:`banner`,role:`note`,children:[H(U,{name:`alert`}),` This vault was saved by a newer version of Keyfold, so it is read-only here. Update the plugin in Standard Notes (Preferences → Plugins) to edit it.`]}),a&&e.mode!==`viewer`&&t.name===`ready`&&H(`div`,{class:`banner`,role:`note`,children:[H(U,{name:`lock`}),` "Prevent editing" is on for this note. You can still reveal and copy secrets.`]}),ct,R.privacyScreen&&!d&&t.name===`ready`&&H(`button`,{type:`button`,class:`privacy-cover`,onClick:()=>{window.focus(),f(!0)},children:[H(U,{name:`eyeOff`,size:28}),H(`span`,{children:Mt()?`Tap to show the vault`:`Click to show the vault`})]})]}),Hi,Vi,ie&&H(Mi,{dialog:ie,onClose:e=>{ie.resolve(e),ae(null)}}),H(Ni,{toasts:ne,onDismiss:e=>re(t=>t.filter(t=>t.id!==e))})]})},Gi=()=>typeof crypto.randomUUID==`function`?crypto.randomUUID():Array.from(crypto.getRandomValues(new Uint8Array(16)),e=>e.toString(16).padStart(2,`0`)).join(``),Ki=e=>e&&/^https?:\/\//.test(e)?e:`*`,qi=`https://app.standardnotes.com/components/assets/`,Ji=e=>{if(/^https?:\/\//i.test(e)||/^data:text\/css[;,]/i.test(e))return e;let t=/\/components\/assets\/([a-z0-9][a-z0-9.-]*)\/([\w.-]+(?:\/[\w.-]+)*\.css)$/i.exec(e);if(t&&!t[0].includes(`..`))return`${qi}${t[1]}/${t[2]}`},Yi=2e3,Xi=[`Shift`,`Alt`,`Control`,`Meta`,`AltGraph`],Zi=class{win;sessionKey;origin;environment;queue=[];callbacks=new Map;themeLoads=new WeakMap;themeGeneration=0;constructor(e=window){this.win=e,e.addEventListener(`message`,this.onMessage),e.addEventListener(`click`,this.onClick),e.addEventListener(`keydown`,this.onKey),e.addEventListener(`keyup`,this.onKey),setTimeout(this.reveal,Yi)}get inMobileApp(){return this.environment===`native-mobile-web`||this.environment===`mobile`}streamContextItem(e){this.send(`stream-context-item`,{},t=>t?.item&&e(t.item),!0)}saveItem(e,t){this.send(`save-items`,{items:[e]},()=>t?.())}send(e,t,n,r=!1){if(!this.sessionKey){this.queue.push({action:e,data:t,callback:n,keep:r});return}let i={action:e,data:t,messageId:Gi(),sessionKey:this.sessionKey,api:`component`};n&&this.callbacks.set(i.messageId,{callback:n,keep:r});let a=this.environment===`mobile`?JSON.stringify(i):i;this.win.parent.postMessage(a,Ki(this.origin))}onMessage=e=>{if(e.source!==this.win.parent||this.win.parent===this.win)return;let t;try{t=typeof e.data==`string`?JSON.parse(e.data):e.data}catch{return}if(t&&typeof t==`object`)switch(t.action){case`component-registered`:if(this.sessionKey||!t.sessionKey)return;this.sessionKey=t.sessionKey,this.origin=e.origin,this.environment=t.data?.environment,this.activateThemes(t.data?.activeThemeUrls),this.send(`themes-activated`,{});for(let e of this.queue.splice(0))this.send(e.action,e.data,e.callback,e.keep);return;case`themes`:this.activateThemes(t.data?.themes);return;case`reply`:{let e=t.original?.messageId,n=e?this.callbacks.get(e):void 0;if(!n)return;n.keep||this.callbacks.delete(e),n.callback(t.data);return}}};onClick=()=>{this.sessionKey&&this.send(`click`,{})};onKey=e=>{if(!this.sessionKey)return;let t=Xi.includes(e.key),n=e.type===`keyup`&&t;(!e.getModifierState?.(`AltGraph`)||t)&&(e.ctrlKey||e.metaKey||e.key===`Control`||e.key===`Meta`||n)&&(e.type===`keydown`&&(e.ctrlKey||e.metaKey)&&e.key.toLowerCase()===`s`&&e.preventDefault(),this.send(e.type===`keydown`?`key-down`:`key-up`,{key:e.key,code:e.code,ctrlKey:e.ctrlKey,metaKey:e.metaKey,shiftKey:e.shiftKey,altKey:e.altKey}))};activateThemes(e){let t=Array.isArray(e)?e.filter(e=>typeof e==`string`):[],n=[...new Set(t.map(Ji).filter(e=>!!e))],r=this.win.document,i=[...r.querySelectorAll(`link[data-sn-theme]`)],a=[];for(let e of n){let t=i.find(t=>t.getAttribute(`href`)===e);if(t){a.push(this.themeLoads.get(t)??Promise.resolve());continue}let n=r.createElement(`link`),o=new Promise(e=>{n.onload=n.onerror=e});this.themeLoads.set(n,o),a.push(o),n.rel=`stylesheet`,n.href=e,n.setAttribute(`data-sn-theme`,``),r.head.appendChild(n)}let o=++this.themeGeneration;Promise.all(a).then(()=>{if(o===this.themeGeneration){for(let e of i)n.includes(e.getAttribute(`href`)??``)||e.remove();this.updateColorScheme(),this.reveal()}})}updateColorScheme(){let e=this.win.document,t=/^rgba?\(([^)]*)\)/.exec(this.win.getComputedStyle(e.body).backgroundColor)?.[1].split(/[\s,/]+/).map(Number);if(!t||t.length<3||t[3]===0)return;let n=.2126*t[0]+.7152*t[1]+.0722*t[2];e.documentElement.style.colorScheme=n<128?`dark`:`light`}reveal=()=>{this.win.document.documentElement.classList.remove(`theme-pending`)}},Qi=e=>e.content?.appData?.[`org.standardnotes.sn`]?.locked===!0,$i=`authentication`,ea=e=>{e.content?.noteType===$i&&(e.content.noteType=`unknown`)},ta=()=>{let e=new Zi(window),t=null;return{mode:`standardnotes`,inMobileApp:()=>e.inMobileApp,subscribe(n){e.streamContextItem(e=>{t=e,n({text:e.content?.text??``,locked:Qi(e),metadataOnly:e.isMetadataUpdate===!0})})},save(n,r){let i=t;i&&(i.content.text=n,i.content.preview_plain=r,i.content.preview_html=``,ea(i),e.saveItem(i))}}},na=e=>{let t=e;return{mode:`demo`,inMobileApp:()=>!1,subscribe(e){queueMicrotask(()=>e({text:t,locked:!1,metadataOnly:!1}))},save(e){t=e}}},ra=e=>({mode:`viewer`,inMobileApp:()=>!1,subscribe(t){queueMicrotask(()=>t({text:e,locked:!0,metadataOnly:!1}))},save(){}}),ia=()=>{try{return window.parent!==window}catch{return!0}},aa=e=>e.split(` `),oa=e=>{let t=new Uint8Array(4+e.length);return new DataView(t.buffer).setUint32(0,e.length),t.set(e,4),t},sa=(...e)=>{let t=new Uint8Array(e.reduce((e,t)=>e+t.length,0)),n=0;for(let r of e)t.set(r,n),n+=r.length;return t},ca=()=>{let e=sa(oa(G(`ssh-ed25519`)),oa(q(32)));return{privateKey:`-----BEGIN OPENSSH PRIVATE KEY-----\n${Ve(sa(G(`openssh-key-v1\0`),oa(G(`aes256-ctr`)),oa(G(`bcrypt`)),oa(q(24)),new Uint8Array([0,0,0,1]),oa(e),oa(q(144)))).match(/.{1,70}/g).join(` +`)}\n-----END OPENSSH PRIVATE KEY-----`,publicKey:`ssh-ed25519 ${Ve(e)} demo@example`}},la=(e,t=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`)=>Array.from(q(e),e=>t[e%t.length]).join(``),ua=e=>{let t=new Date;return t.setDate(t.getDate()+e),t.toISOString().slice(0,10)},da=()=>{let e=ca(),t=rt();return t.entries.push(it(`mnemonic`,{label:`Example: cold storage`,description:`Public BIP39 test vector. Do not send funds to it.`,chain:`Bitcoin`,wallet:`Coldcard`,tags:[`example`,`long-term`],favorite:!0,words:aa(`legal winner thank year wave sausage worth useful legal winner thank yellow`),passphrase:`example passphrase`,passphraseHint:`Example hint only`,derivationPath:`m/84'/0'/0'`,createdOn:`2021-03-14`,backups:[{id:`b1`,location:`Steel plate in home safe`,verifiedOn:nt()}]}),it(`mnemonic`,{label:`Example: multisig key 2 of 3`,chain:`Bitcoin`,wallet:`Trezor`,tags:[`example`,`multisig`],words:aa(`letter advice cage absurd amount doctor acoustic avoid letter advice cage above`),derivationPath:`m/48'/0'/0'/2'`,createdOn:`2022-08-02`,backups:[{id:`b2`,location:`Bank deposit box`,verifiedOn:`2025-01-10`}]}),it(`mnemonic`,{label:`Example: DeFi hot wallet`,chain:`Ethereum`,wallet:`MetaMask`,tags:[`example`],words:aa(`${`abandon `.repeat(23)}art`),derivationPath:`m/44'/60'/0'/0/0`,createdOn:`2023-11-20`}),it(`privateKey`,{label:`Example: paper wallet`,description:`WIF test vector from the Bitcoin wiki.`,chain:`Bitcoin`,tags:[`example`],secret:`5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ`,createdOn:`2013-04-01`}),it(`sshKey`,{label:`Example: deploy key`,description:`Random bytes in OpenSSH format, not a working key.`,service:`github.com`,account:`git`,tags:[`example`],secret:e.privateKey,passphrase:`example passphrase`,publicInfo:e.publicKey,expiresOn:ua(365)}),it(`apiKey`,{label:`Example: CI token`,description:`Random characters in GitHub token format, not a real token.`,service:`GitHub`,account:`release workflow`,tags:[`example`],secret:`ghp_${la(36)}`,expiresOn:ua(12)}),it(`recoveryCodes`,{label:`Example: exchange 2FA backup codes`,service:`Kraken`,account:`you@example.com`,tags:[`example`],secret:Array.from({length:8},()=>`${la(4,`0123456789`)}-${la(4,`0123456789`)}`).join(` +`)})),t.entries.forEach((e,t)=>e.updatedAt=new Date(Date.now()-t*6e4).toISOString()),bt(t)},fa=document.documentElement.hasAttribute(`data-viewer`),pa=!fa&&ia();document.documentElement.classList.toggle(`standalone`,!pa),pa||document.documentElement.classList.remove(`theme-pending`);var ma=document.getElementById(`app`);pa?M(H(Wi,{host:ta()}),ma):fa||location.hash===`#open`?M(H(Ti,{offlineViewer:fa,onOpen:e=>M(H(Wi,{host:ra(e)}),ma)}),ma):M(H(Wi,{host:na(da())}),ma)})(); \ No newline at end of file diff --git a/packages/io.github.nickstruglia.keyfold/prebuilt/icon.svg b/packages/io.github.nickstruglia.keyfold/prebuilt/icon.svg new file mode 100644 index 0000000..0e4b5fd --- /dev/null +++ b/packages/io.github.nickstruglia.keyfold/prebuilt/icon.svg @@ -0,0 +1 @@ + diff --git a/packages/io.github.nickstruglia.keyfold/prebuilt/index.html b/packages/io.github.nickstruglia.keyfold/prebuilt/index.html new file mode 100644 index 0000000..eaab82d --- /dev/null +++ b/packages/io.github.nickstruglia.keyfold/prebuilt/index.html @@ -0,0 +1,16 @@ + + + + + + + + + Keyfold + + + + +
+ + diff --git a/packages/io.github.nickstruglia.keyfold/prebuilt/keyfold-viewer.html b/packages/io.github.nickstruglia.keyfold/prebuilt/keyfold-viewer.html new file mode 100644 index 0000000..533cb4a --- /dev/null +++ b/packages/io.github.nickstruglia.keyfold/prebuilt/keyfold-viewer.html @@ -0,0 +1,512 @@ + + + + + + + + + +Keyfold offline viewer + + + + +
+ + + diff --git a/yarn.lock b/yarn.lock index d06ce55..d1f3956 100644 --- a/yarn.lock +++ b/yarn.lock @@ -27769,6 +27769,12 @@ __metadata: languageName: node linkType: hard +"sn-keyfold@workspace:packages/io.github.nickstruglia.keyfold": + version: 0.0.0-use.local + resolution: "sn-keyfold@workspace:packages/io.github.nickstruglia.keyfold" + languageName: unknown + linkType: soft + "sn-stylekit@npm:2.0.19": version: 2.0.19 resolution: "sn-stylekit@npm:2.0.19"